一般情况下,哪些情况需要模板参数完整
What are the cases in general which require template argument to be complete?
考虑简单的代码:
struct x;
template<typename> void func(){}
int main() {
func<x>();
return 0;
}
上面的代码不需要类x
是完整的,还有其他情况不需要x
是完整的吗。一般来说,哪些情况需要模板参数完整?
如果某些模板实例化导致生成要求类型完整的代码,则模板参数必须是完整的类型,例如,任何需要模板大小的构造——参数、成员访问的使用等。
在您的情况下,根本不使用模板参数。任何实例化都不要求类型完整。我们很容易造成错误:
struct x;
template<typename T> void func()
{ T a; } //requires complete type
int main() {
func<x>();
}
GCC表示:
错误:"x a"具有不完整的类型
如果我们使用指针或引用,则不需要完整的类型:
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
要求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;
}
这和其他地方都一样:如果
- 您只使用指向类型的指针
- 或引用
- 或将其用作声明中的参数
而不使用指针/引用来访问成员。
相关文章:
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- 如何在不知道C++中有多少可选参数的情况下在循环中使用va_arg?
- 如何在不强制转换每个参数的情况下删除初始值设定项列表中从 int 到 char 的缩小转换?
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 如何在不传递命令行参数的情况下在 c++ 中设置环境变量
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 是否可以在不填充自己的参数的情况下将模板函数作为参数传递?
- 我应该如何在没有变量的情况下将相同的参数传递给 CMAKE 中的多个目标?
- C++复杂情况的比较器通过参数问题
- 是否可以在不扣除的情况下将模板参数转发到 make_*?
- 为什么或在什么情况下,你会将参数作为C++中的引用(或指针)传递给函数?
- 如何在给定 std::variant 的情况下检索模板参数包?
- 处理一般情况混合类型和非类型的可变参数模板
- C++ 模板类:运行时给出的模板参数,如何避免重复大开关情况?
- 在C++中,有没有一种方法可以让我在不传递参数的情况下拥有一个函数
- 如何在没有参数包的情况下编写变差函数
- 如何在不使用文件扩展名的情况下使用命令行参数打开C++中的文本文件?
- 此函数如何在不传递任何参数的情况下工作?