也许这是个蹩脚的问题,但我不明白!如果我将<string>或<vector>包含在多个翻译单元(不同的.cpp)中,为什么它不破坏ODR?据我所知,每个.cpp都是不同的编译方式,因此向量的方法代码将分别为每个对象文件生成,对吗?所以链接者应该发现它并抱怨。即使不会(我怀疑这是模板的特例),当我将所有的代码链接在一起时,它会在每个单元中使用一个代码或不同的克隆代码集吗?
发布于 2015-12-31 23:30:44
同样,任何模板定义都不会破坏ODR -- ODR明确指出,只要模板定义确实是重复的(而且,由于它们是重复的,因此不可能发生冲突或歧义),模板定义就可以跨翻译单元重复。
[C++14: 3.2/6]:可以有多个类类型的定义(第9条)、枚举类型(7.2)、带外部链接的内联函数(7.1.2)、类模板(第14条)、非静态函数模板(14.5.6)、类模板的静态数据成员(14.5.1.3)、类模板的成员函数(14.5.1.1)或程序中未指定某些模板参数的模板专门化(14.7、14.5.5),只要每个定义出现在不同的转换单元中,并提供满足以下要求的定义。
在同一个翻译单元中包含<vector>的多个内容是明确允许的,并且有效地被省略,这很可能是由"#ifndef“头保护器完成的。
发布于 2015-12-31 23:57:40
该标准对模板有一个特殊的例外,该模板允许重复功能,否则会违反ODR (例如具有外部链接和非内联成员函数的函数)。来自C++11 3.2/5:
如果D是一个模板,并且定义在多个翻译单元中,那么上述要求既应适用于模板定义(14.6.3)中使用的模板的包围作用域中的名称,也应适用于实例化点上的依赖名称(14.6.2)。如果D的定义满足所有这些要求,则程序应表现为有一个D的单一定义。如果D的定义不满足这些要求,则行为是未定义的。
发布于 2015-12-31 23:32:34
ODR没有声明一个结构只会在所有编译单元中被声明一次--它指出,如果您在多个编译单元中声明一个结构,那么它必须是同一个结构。如果您有两个名称相同但内容不同的vector类型,就违反了ODR。在这一点上,链接器会被混淆,而您会混淆代码和/或错误。
https://stackoverflow.com/questions/34552380
复制相似问题