为什么 C++ 的 <vector> 模板化 class 没有违反一个定义规则?
Why C++'s <vector> templated class doesn't break one definition rule?
也许这是一个蹩脚的问题,但我不明白!
如果我在多个翻译单元(不同的 .cpp)中包含 <string>
或 <vector>
为什么它不会破坏 ODR?
据我所知,每个 .cpp 的编译方式都不同,因此将为每个目标文件分别生成 vector 的方法代码,对吧?
所以 linker 应该发现它并抱怨。
即使它不会(我怀疑它是模板的特殊情况)它会在每个单元中使用一个代码还是不同的克隆代码集,当我一起 link 时???
同样,任何 模板定义都不会破坏 ODR — ODR 特别指出模板定义可以跨翻译单元重复,只要它们是字面上的重复(而且,因为它们是重复的,所以不可能有冲突或歧义。
[C++14: 3.2/6]:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements [..]
明确允许在同一个翻译单元中多次包含 <vector>
并有效地省略,很可能是“#ifndef
”header 守卫。
ODR 没有说明一个结构在所有编译单元中只能声明一次——它声明如果您在多个编译单元中声明一个结构,它必须是 相同的 结构。如果您有两个名称相同但内容不同的单独 vector
类型,就会违反 ODR。那时链接器会感到困惑,你会混淆代码 and/or 错误。
该标准有一个特殊的模板例外,允许复制否则会违反 ODR 的函数(例如具有外部链接的函数和 non-inline 成员函数)。来自 C++11 3.2/5:
If D is a template and is defined in more than one translation unit,
then the preceding requirements shall apply both to names from the
template’s enclosing scope used in the template definition (14.6.3),
and also to dependent names at the point of instantiation (14.6.2). If
the definitions of D satisfy all these requirements, then the program
shall behave as if there were a single definition of D. If the
definitions of D do not satisfy these requirements, then the behavior
is undefined.
也许这是一个蹩脚的问题,但我不明白!
如果我在多个翻译单元(不同的 .cpp)中包含 <string>
或 <vector>
为什么它不会破坏 ODR?
据我所知,每个 .cpp 的编译方式都不同,因此将为每个目标文件分别生成 vector 的方法代码,对吧?
所以 linker 应该发现它并抱怨。
即使它不会(我怀疑它是模板的特殊情况)它会在每个单元中使用一个代码还是不同的克隆代码集,当我一起 link 时???
同样,任何 模板定义都不会破坏 ODR — ODR 特别指出模板定义可以跨翻译单元重复,只要它们是字面上的重复(而且,因为它们是重复的,所以不可能有冲突或歧义。
[C++14: 3.2/6]:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements [..]
明确允许在同一个翻译单元中多次包含 <vector>
并有效地省略,很可能是“#ifndef
”header 守卫。
ODR 没有说明一个结构在所有编译单元中只能声明一次——它声明如果您在多个编译单元中声明一个结构,它必须是 相同的 结构。如果您有两个名称相同但内容不同的单独 vector
类型,就会违反 ODR。那时链接器会感到困惑,你会混淆代码 and/or 错误。
该标准有一个特殊的模板例外,允许复制否则会违反 ODR 的函数(例如具有外部链接的函数和 non-inline 成员函数)。来自 C++11 3.2/5:
If D is a template and is defined in more than one translation unit, then the preceding requirements shall apply both to names from the template’s enclosing scope used in the template definition (14.6.3), and also to dependent names at the point of instantiation (14.6.2). If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.