inline
函数提供了一个定义规则的弱化 - 允许多个定义,尽管有一些限制。我在网上找到的一个措辞是
要求是每个定义应该相同,这意味着它应该包含相同的标记并引用相同的项目。
虽然我承认我不知道这是否是最终的。我也不确定它有多严格。
我正在考虑使用class
定义和/或inline
函数创建标题的情况我想成为#include
- 是否可以在C +中编译+ 03,C ++ 11,甚至更晚的标准。使用__cplusplus
宏来有条件地更改代码是很自然的,但是ODR会发挥作用吗?例如,有条件地:
typedef
。class
。throw()
或noexcept
。 (这一点尤为重要,因为每个析构函数都会在C ++ 11中选择隐式noexcept
。)constexpr
。override
和/或final
标记功能。[[noreturn]]
和/或[[nodiscard]]
。[[maybe_unused]]
。[[fallthrough]]
。但如果想要启用#include
这些标题库以不同标准编译并且仍然可以安全使用的库,那么实际上允许哪些 - 如果有的话 -
答案 0 :(得分:0)
一般情况下,你不能安全地做任何这些事情。安全使用说两种类的定义只有两种方法。通过简单的方式,您可以简单地编译两个单独的进程,这些进程通过例如共享内存。更简单的是,如果出现以下情况,您可以使用两个以两种不同方式定义相同符号A的库:
如果你做了所有这些,那么A确实是库的实现细节,你可以使用多个以不同方式定义A的库。如果其中任何一个不满意,那么你不能保证上述任何一个都可以工作(虽然有些人会这样做)。
对于不熟悉链接器的人来说,最令人惊讶的结果之一是,如果lib1和lib2都使用符号A,即使它们阻止任何通过头部的泄漏,如果A的可见性是公开的,那么单个定义将在两个库中使用A.因此lib2将使用lib1的定义,反之亦然。这很容易导致UB。
在* nix系统上,公共可见性是默认设置,因此您需要确保隐藏符号,这有点神秘。