C ++ 17之前/之后的constexpr静态成员 [英] constexpr static member before/after C++17
问题描述
据我所知,一种非常常见的情况是
As far as I can see, a very common situation is something like
template<int i> class Class
{
public:
static constexpr int I = i;
static constexpr int J = constexprFunction(i);
// further Class implementation
};
我通常会看到这个错误(实际上,我的大部分问题是因为我忘记了,不知道,正确的问题是什么),如果成员被滥用,则忘记附加定义:
Almost as common I see the mistake (in fact most of my questions here are because I forgot it and did not know, what the proper question had been) to forget the additional definition if the member are odr-used:
template<int i> constexpr int Class<i>::I;
template<int i> constexpr int Class<i>::J;
现在我阅读 cppreference:定义和ODR 和 cppreference:静态成员,该状态表示对于C ++ 17不推荐使用。这对我来说似乎很棒,因为它避免了很多错误。但是还有其他问题:
Now I read cppreference: Definitions and ODR and cppreference: static members, which state, that this is deprecated for C++17. This seems great to me, because it avoids a lot of errors. But there are other questions, that came up:
1)除了使附加定义无用之外,此更改是否还有其他原因吗? (另请参见此问题的最后一段)
1) Has this change other reasons than making the additional definitions useless? (See also last paragraph of this question)
2)在 cppreference:静态成员它似乎也适用于 const static
成员-但规则仅规定了 constexpr
成员。它是否适用于 const static
成员?
2) In the last example of cppreference: static members it seems also to apply on const static
member - but the rule states only the constexpr
member. Will it apply on const static
member or not?
3)我发现的所有示例都使用了简单的定义,例如 Class :: I
-对于 Class:J
和的情况,是否也都适用? constexpr
函数?
3) All examples I found were using a simple definition like Class::I
- does it all hold also for the situation at Class:J
with constexpr
functions?
简要说明C ++ 17之前和C ++ 17之前的最佳实践是什么。总而言之,这对我来说似乎是一个非常棘手的更改,因为它将使很多代码(以前据我了解...)变成很多代码,这些代码以前是格式错误,无需诊断。因此,使用较旧的(17岁之前的)编译器会生成仍然仍然需要格式错误的非诊断代码,但是只要不需要使用odr,这些代码就不会抱怨。
A brief state what the best practices are before C++17 and with C++17 would be great. All in all this seems a very tricky change to me, because it will make a lot of code, which was "ill-formed non diagnostic required" before, to good code (as far as I understand...). And consequently there will be code produced, that is still "ill-formed non diagnostic required" with older (pre 17) compiler - but these will not complain, as long as no odr-use is required.
编辑:更正了文本,由亚伦·麦克戴(Aaron McDaid)建议。
Edit: Corrected the text, suggested by Aaron McDaid.
推荐答案
此更改是由于内联变量提案( P0386 )。 静态constexpr
表示内联
,从而使定义变得多余。
This change is due to the inline variables proposal (P0386). static constexpr
will imply inline
, making definitions redundant.
在附件D中,添加新的小节重新声明静态constexpr数据成员 DX,其内容如下:
为了与先前的C ++国际标准兼容,constexpr静态数据成员可以在没有初始化程序的类外部重复声明。
In Annex D, add a new subclause, "Redeclaration of static constexpr data members", D.X, with the following content: For compatibility with prior C++ International Standards, a constexpr static data member may be redundantly redeclared outside the class with no initializer. This usage is deprecated.
[示例:
struct A {
static constexpr int n = 5; // definition (declaration in C++2014)
};
const int A::n; // redundant declaration (definition in C++2014)
-结束示例]
关于您的问题:
是否有其他原因?而不是使附加定义无用?
Has this change other reasons than making the additional definitions useless?
本质上,没有。然而,除了您提到的用途以外,它还有其他用途(请参见问题)。这项提议引起争议,因为它可能鼓励使用可变的全局状态。
In essence, no. Yet it has additional uses besides the one you noted (see this question). This proposal was controversial because it might encourage the use of a mutable global state.
它将应用于
const static
成员与否?
否。 除非,您将其注释为 inline
。
No. Unless you annotate it as inline
.
对于
Class:J
具有constexpr
函数的情况,这是否也适用?
does it all hold also for the situation at
Class:J
withconstexpr
functions?
是。该提案处理链接,但不影响初始化规则。
Yes. The proposal deals with linking but does not affect initialization rules.
这篇关于C ++ 17之前/之后的constexpr静态成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!