你好,祝你好运。
以下代码片段编译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的编译器开关会强制编译器处理整个模板(因此这段代码片段会触发编译错误)?
答案 0 :(得分:11)
如果要使用多种类型测试模板,可以触发类型的手动实例化,如:
// at namespace level
template class Test<int>;
类模板的显式实例化会自动触发所有成员的实例化,这似乎就是你想要的。
实际问题是该语言旨在明确允许您要避免的行为。当隐式实例化类模板时,编译器将仅实例化那些使用的方法。该功能的主要用例是某些方法可能对实例化类型施加比其他方法更严格的要求,如果所有方法都实例化始终那么类模板只能用于那些实现更严格的类型要求。
通过允许编译器仅实例化那些使用的方法,类模板可以用于不满足所有方法的所有要求的类型,只要它们满足方法的要求即可。实际上是用的。
operator[]
中的std::map<>
常见示例要求value_type
默认可构造(operator[]
将创建新对象< em>默认初始化如果容器中不存在该键并返回对它的引用)。只要您不使用std::map
(或强制执行的任何其他成员函数),该语言中的行为允许您对不是 default-constructible 的类型使用operator[]
那个要求)。