C++:强制完成模板编译 (MSVC/G++)
你好,祝你有美好的一天。
以下代码片段在 cl.exe (15.00.30729.01) 和 mingw-g++ (4.4.0) 上编译:
template<typename T> class Test{
public:
T t;
void error(){
int doesNotExist = 6;
return doesNotExist;//<---- void function returning result
}
};
int main(int argc, char** argv){
Test<int> test;
return 0;
}
另外,在 cl.exe 上你甚至可以摆脱这样的事情:
template<typename T> class Test{
public:
T t;
void error(){
doesNotExist = 6;//<---- undeclared variable
return doesNotExist;//<---- void function returning result
}
};
现在,这显然会发生,因为编译器不会创建内容模板类的方法,直到有人调用它们。但是,当您设计大型模板类时,这可能会带来问题(因为您很可能忘记在某处添加对新方法的测试调用)。
问题:
是否有 g++ 或 cl.exe 的编译器开关会强制编译器处理整个模板(因此此代码片段将触发编译错误)?
Hello and good day to you.
Following code fragment compiles on cl.exe (15.00.30729.01) and mingw-g++ (4.4.0):
template<typename T> class Test{
public:
T t;
void error(){
int doesNotExist = 6;
return doesNotExist;//<---- void function returning result
}
};
int main(int argc, char** argv){
Test<int> test;
return 0;
}
Also, on cl.exe you can even get away with something like this:
template<typename T> class Test{
public:
T t;
void error(){
doesNotExist = 6;//<---- undeclared variable
return doesNotExist;//<---- void function returning result
}
};
Now, this obviously happens because compiler does not create contents for methods of a template class until somebody calls them. However, this may pose problems when you're designing large template class (because you're very likely to forget to add test call to new method somewhere).
The question:
Is there a compiler switch for g++ or cl.exe that would force compiler to process entire template (so this code fragment will trigger compilation error)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您想使用多种类型测试模板,则可以触发类型的手动实例化,如下所示:
类模板的显式实例化会自动触发所有成员的实例化,这似乎正是您想要的。
实际的问题是该语言被设计为明确允许您想要避免的行为。当隐式实例化类模板时,编译器将仅实例化那些使用的方法。该功能的主要用例是,某些方法可能对实例化类型施加比其他方法更严格的要求,如果所有方法始终都被实例化,那么类模板只能与满足更严格要求的类型一起使用要求。
通过允许编译器仅实例化那些使用的方法,类模板可以与不满足所有方法的所有要求的类型一起使用,只要它们满足实际使用的方法的要求即可。
一个常见的示例是
std::map
中的operator[]
,它要求value_type
是可默认构造的 (如果容器中不存在该键,operator[]
将创建一个默认初始化的新对象,并返回对其的引用)。该语言中的行为允许您在不可默认构造的类型上使用std::map
,只要您不使用operator[]< /code> (或强加该要求的任何其他成员函数)。
If you want to test the template with a couple of types, you can trigger manual instantiations of the types, as in:
Explicit instantiations of class templates automatically trigger the instantiation of all members, which seems to be what you want.
The actual problem is that the language is designed to explicitly allow the behavior that you want to avoid. When a class template is implicitly instantiated, the compiler will instantiate only those methods that are used. The main use case of the feature is that some methods might impose stricter requirements on the instantiating type than others, if all methods were instantiated always then the class template could only be used with those types that fulfill the stricter requirements.
By allowing the compiler to only instantiate those methods that are used, the class template can be used with types that don't meet all of the requirements of all of the methods, as long as they meet the requirements of the methods that are actually used.
A common example is
operator[]
instd::map<>
that requires thevalue_type
to be default-constructible (operator[]
will create a new object default initialized if the key is not present in the container and return a reference to it). The behavior in the language allows you to usestd::map
on types that are not default-constructible as long as you don't useoperator[]
(or any other member function that imposes that requirement).