c – 模板变量是否允许在多个翻译单元中并有效合并?
请参阅以下内容:
https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule http://eel.is/c++draft/basic.def.odr#12 它声明允许类模板的多个定义,类模板的静态数据成员,部分模板特化等,并将作为单个定义.太棒了…但它没有提到变量模板吗? 如果我在多个翻译单元中有以下内容: template<typename T> T my_data{}; inline void test() { my_data<int> = 1; } 是否会为每个翻译单元提供他们自己的my_data定义,从而产生多个符号,或者它们是否会有效地合并到程序中的单个定义中,其中一个翻译单元中的调用test()将修改另一个翻译单元的变量? 标准中的哪个部分提到了这种行为? 解决方法
根据c 14标准
[basic.def]/4:
因此,如果my_data< T>如果在多个翻译单元中使用相同的模板参数,则应该有一个odr违规(没有任何诊断).内联变量出现在c 17中以解决该问题,这就是为什么type_traits * _v系列变量模板被内联声明的原因. 在实践中,使用Gcc和Clang(至少,我不能检查其他编译器),你不会得到任何odr违规,因为模板变量具有“模糊的链接”(就好像它们被声明为内联). 你可以用nm检查它.如果你运行这个命令行g -c test.cpp -std = c 14&& nm test.o | c filt | grep my_data,你应该看到my_data< int>是根据nm文档的类别的符号:
在Core issue #1849年,人们可以阅读这个不起眼的句子:
我敢打赌,如果所有编译器都给变量模板一个模糊的联系,那么标准的未来修订可能会反映出来.但是现在我们应该使用内联说明符,因为它在stl中完成. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |