C++ 为什么是;内联“;静态内联变量是否需要?

C++ 为什么是;内联“;静态内联变量是否需要?,c++,inline,c++17,C++,Inline,C++17,C++17允许通过以下方式定义静态成员变量: class X { public: static inline int i = 8; }; 要求内联规范背后的基本原理是什么?为什么不简单地允许程序员编写呢 static int i = 8; 在没有内联的类?中,它只显式地声明为一个声明。如 类中非内联静态数据成员的声明 定义不是定义,可能是其他类型的不完整定义 比cv无效。非静态数据成员的定义 类定义中的内联定义应出现在名称空间中 包含成员的类定义的范围 基本原理很可能是保

C++17允许通过以下方式定义静态成员变量:

class X {
  public:
    static inline int i = 8;
};
要求
内联
规范背后的基本原理是什么?为什么不简单地允许程序员编写呢

    static int i = 8;

在没有内联
的类?

中,它只显式地声明为一个声明。如

类中非内联静态数据成员的声明 定义不是定义,可能是其他类型的不完整定义 比cv无效。非静态数据成员的定义 类定义中的内联定义应出现在名称空间中 包含成员的类定义的范围

基本原理很可能是保持遗留代码完整有效。回想一下,我们可以在类定义本身中初始化整型常量,因为大约永远都是这样。但是使用它们的odr仍然需要在一些翻译单元中进行类外定义

因此,在现有的代码库中,隐式内联这些变量可能会有问题。当添加核心语言特性时,委员会总是考虑向后兼容性

例如,考虑这个有效的C++ 03类定义:

struct foo {
    static const int n = 3;
    double bar[n];
};
n
可以用作一个常量表达式来定义
条的范围
,它不被视为odr使用。现在我们把它写成
constexpr
1,但是上面的仍然有效。但也有一些情况下,
n
必须使用odr(想象一下它的地址,或者绑定到它的引用,等等)。它们可能不多,也可能不常见,但某些API有疯狂的需求,最终需要这样做

const int foo::n;
出现在某个翻译单元中

现在,如果
静态内联int i=8突然隐式地
内联
,上面的定义(即在现有代码库中)将是odr冲突。现在,以前格式良好的代码是格式不正确的。所以最好只允许显式
内联
在这里生效,因为只有新代码才会真正生效


1有人可能会争辩说,
static constexpr
变量可能有同样的问题(但它们是隐式内联的)。但IIRC的原始措辞允许在不破坏现有规范的情况下进行这种更改。它基本上已经“内联”了,除了名字。

勾选此项,它可以让您了解“为什么”。如果有一个“有问题”行为的实际示例,这个答案会更好。OP的代码建议已经格式不正确,因此更改不会破坏现有代码。但这有点inconsistent@M.M-OP的代码是。但同样的处理方法也必须适用于格式良好的const数据成员。不管怎样,我正在扩张。只是一个moment@Yakk-更好?我觉得我可能把
constexpr
的注释弄虚作假了;事实上,
const int foo::ninline
而导致ODR冲突,code>不是
inline
关键字的基本部分,而是
inline
关键字的实现选择。因此,假设
inline
的中断现在是“因为他们选择在声明中使用
inline
将违反ODR,然后在没有
inline
的情况下定义它”,这就引出了一个问题“他们为什么选择这是ODR违反”。我怀疑是因为与
内联
函数类似?但还有其他原因吗?