在模板中使用不完整的模板类型
Use of incomplete template types in templates
这是对 的跟进,其中答案是格式错误,不需要诊断,在模板中使用仅在模板实例化时完成但不是在它定义的时候。
我的后续问题是,在不完整类型本身依赖于模板参数的情况下,这是否仍然成立?因为它似乎不是。以下在 Godbolt 上的所有编译器中编译,即使 foo::do_stuff()
使用 foo_wrapper::value()
只给出一个 class 模板 foo_wrapper
最终将存在的前向声明。
#include <iostream>
template<typename T>
class foo_wrapper;
template<typename T>
class foo {
foo_wrapper<T>& parent_;
public:
foo(foo_wrapper<T>& wrapped) : parent_(wrapped)
{}
void do_stuff() {
std::cout << "do stuff " << parent_.value() << "\n";
}
};
template<typename T>
class foo_wrapper {
foo<T> foo_;
T value_;
public:
foo_wrapper(T n) :
foo_(*this),
value_(n)
{}
void do_stuff() {
foo_.do_stuff();
}
T value() const {
return value_;
}
};
int main()
{
foo_wrapper<int> fw(42);
fw.do_stuff();
}
这是合法的。
经验法则是在实例化模板时检查依赖于模板参数的所有内容。其他所有内容要么在第一次看到模板时检查, 要么 在实例化时检查(例如,MSVC 倾向于晚检查所有内容,而 Clang 倾向于尽早检查)。
这是对
我的后续问题是,在不完整类型本身依赖于模板参数的情况下,这是否仍然成立?因为它似乎不是。以下在 Godbolt 上的所有编译器中编译,即使 foo::do_stuff()
使用 foo_wrapper::value()
只给出一个 class 模板 foo_wrapper
最终将存在的前向声明。
#include <iostream>
template<typename T>
class foo_wrapper;
template<typename T>
class foo {
foo_wrapper<T>& parent_;
public:
foo(foo_wrapper<T>& wrapped) : parent_(wrapped)
{}
void do_stuff() {
std::cout << "do stuff " << parent_.value() << "\n";
}
};
template<typename T>
class foo_wrapper {
foo<T> foo_;
T value_;
public:
foo_wrapper(T n) :
foo_(*this),
value_(n)
{}
void do_stuff() {
foo_.do_stuff();
}
T value() const {
return value_;
}
};
int main()
{
foo_wrapper<int> fw(42);
fw.do_stuff();
}
这是合法的。
经验法则是在实例化模板时检查依赖于模板参数的所有内容。其他所有内容要么在第一次看到模板时检查, 要么 在实例化时检查(例如,MSVC 倾向于晚检查所有内容,而 Clang 倾向于尽早检查)。