考虑简单的代码:
struct x;
template<typename> void func(){}
int main() {
func<x>();
return 0;
}
上面的代码不要求类x
完整,是否还有其他情况不需要x
完成? 。另外一般情况下,需要模板参数完成的情况是什么?
答案 0 :(得分:4)
如果某些模板实例化导致生成要求类型完整的代码,例如,模板参数必须是完整类型。任何需要模板大小的构造参数,成员访问的使用等等。
在您的情况下,根本不使用模板参数。没有实例化将要求类型完整。我们可以很容易地导致错误:
struct x;
template<typename T> void func()
{ T a; } //requires complete type
int main() {
func<x>();
}
海湾合作委员会说:
错误:&#39; x a&#39;有不完整的类型
如果我们使用指针或引用,则不需要完整的类型:
template<typename T> void func()
{ T* a; } //does not need complete type
请注意,类型需要在实例化时间完成。这意味着只要您在模板中使用和该模板的实例化之间定义结构,您就可以了。这很干净地编译:
struct x;
template<typename T> void func()
{ T a; } //requires complete type
struct x{}; //we now define x
int main() {
func<x>(); //instantiation
}
请注意,模板类的成员函数仅在使用时实例化。因此,只要您不使用这些成员函数,就可以使用具有成员函数的模板类,该模板类需要具有不完整模板参数的完整类型。
例如,使用以下代码:
struct x;
template <typename T>
struct Foo {
void bar() {
}
void baz() {
T a;
}
};
这是有效的:
Foo<x> a;
a.bar();
但这不是:
Foo<x> a;
a.baz(); //requires complete type
答案 1 :(得分:3)
要求x
完成,您需要了解x
在内存中的排列方式。例如:
struct x;
template<typename> void func() {
// Compiler error: what is x::foo ???
std::cout << x.foo() << std::endl;
}
int main() {
func<x>();
return 0;
}
答案 2 :(得分:3)
与其他地方相同:如果
,您可以使用不完整的类型不使用指针/引用来访问成员。