模板变量是否可以在多个翻译单元中使用并有效地合并?

田田

请参阅以下内容:

https://zh.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>在多个翻译单元中与相同的模板参数一起使用ord,则应该具有odr-violation(无任何诊断)。inline变量出现在c ++ 17中以解决该问题,这就是为什么声明type_traits* _v系列变量模板的原因inline

在实践中,使用Gcc和Clang(至少,我无法检查其他编译器),因为模板变量具有“模糊链接”(就像它们被声明为内联一样),您将不会遇到任何odr违例。

您可以使用进行检查nm如果运行此命令行g++ -c test.cpp -std=c++14 && nm test.o | c++filt | grep my_data,应该看到这是根据文档my_data<int>的categorie的符号unm

该符号是唯一的全局符号。这是对ELF符号绑定的标准集合的GNU扩展。对于这样的符号,动态链接器将确保在整个过程中只有一个使用此名称和类型的符号。


核心问题#1849中,您可以阅读以下晦涩的句子:

在6.2 [basic.def.odr]第6段中,何时可以在程序中多次声明实体的描述不是,但应该讨论变量模板。

我敢打赌,如果所有编译器都为变量模板提供模糊的链接,那么将来对该标准的修订可能会反映出这一点。但是现在我们应该像在stl中那样使用内联说明符。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

R:有效地合并1000多个变量

您可以有效地将by变量强制为数字合并吗?

Python:在多个数组列中计数零并有效地存储它们

有效地检查多个变量是否不为null,未定义或为空

如何避免同步并有效地使用异步?

有效地在多个函数中使用多个参数

是否可以有效地扩展HTMLProps类型?

是否可以使用 prisma 有效地更改表名和列名?

如何有效地在 Unity 中使用继承?

使用Python有效地遍历对象变量

有效地使用多个Asyncio队列

有效地使用多个条件

有什么方法可以在位集中表示〜27个整数并有效地访问它们?

SQL-使用CTE并有效地选择特定row_number()处的行

有效地合并具有多个匹配键的大型对象数据集

有效地使用ConcurrentHashMap?

有效地使用parfor

是否有任何解决方案可以有效地使用 Shopify API 创建 20000 多种产品

在保持顺序的同时有效地合并多个地图

如何最有效地添加一些信息以在Java中使用多个线程列出?

如何在Python 2.7中使用多个键有效地解析JSON数据?

解析文本文件并有效地对其进行拆分

解析错误原始字符串并有效地选择错误类型

随机生成ID并有效地将其持久化在Java中

从Sqlite表中选择线元组并有效地对元组进行排序

C#MVC遍历列表并有效地更新每个记录

熊猫数据框采用列并有效地将其追加为新行

如何遍历数组并有效地更改字符?

是否可以使用管道在Mongo中有效地进行排序,分组和限制?