强制完成模板编译(MSVC/ g++)
C++: force complete template compilation (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的编译器开关是否会强制编译器处理整个模板(因此此代码片段将触发编译错误)?
如果您想用几个类型测试模板,您可以触发这些类型的手动实例化,如下所示:
// at namespace level
template class Test<int>;
类模板的显式实例化会自动触发所有成员的实例化,这似乎是您想要的。
实际的问题是该语言被设计成显式地允许您想要避免的行为。当隐式实例化类模板时,编译器将只实例化使用的方法。该特性的主要用例是某些方法可能对实例化类型施加比其他方法更严格的要求,如果所有方法都被实例化总是,那么类模板只能与满足更严格要求的类型一起使用。
通过允许编译器只实例化那些被使用的方法,类模板可以用于不满足所有方法的所有要求的类型,只要它们满足实际使用的方法的要求。
一个常见的例子是std::map<>
中的operator[]
,它要求value_type
是默认可构造的 (operator[]
将创建一个新的对象默认初始化,如果键不存在于容器中,并返回对它的引用)。该语言的行为允许您在非默认可构造的类型上使用std::map
,只要您不使用operator[]
(或任何其他强加该要求的成员函数)。
相关文章:
- MSVC多行宏编译器错误
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- MSVC是否支持C++11样式的属性而不是__declspec
- MSVC将仅移动结构参数解释为指针
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 有与__builtin__FUNCTION()等效的MSVC吗
- 为什么 gcc 编译这个而 msvc 没有
- 看起来is_nothrow_constructible_v()在MSVC中被破坏了,我错了吗
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- MSVC 忽略 [[maybe_unused]] 的功能?
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- MSVC中的宏观扩展问题
- "Ill-defined for-loop - loop executes infinitely" (MSVC C6295)
- __CHAR_BIT__宏是否为 MSVC 编译器预定义?
- 不正确的操作数类型 MSVC
- 使用 MSVC 调试类型
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- MSVC(Visual C++)是否有等效的-weffc ++?
- 命名空间范围内的外部 - GCC vs clang vs msvc
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?