简体   繁体   English

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:如果成员被 odr 使用,我看到的错误几乎是常见的(实际上我在这里的大部分问题都是因为我忘记了它并且不知道正确的问题是什么)忘记附加定义:

template<int i> constexpr int Class<i>::I;
template<int i> constexpr int Class<i>::J;

Now I read cppreference: Definitions and ODR and cppreference: static members , which state, that this is deprecated for C++17.现在我读了cppreference: Definitions and ODRcppreference: static members ,其中指出,这在 C++17 中已被弃用。 This seems great to me, because it avoids a lot of errors.这对我来说似乎很棒,因为它避免了很多错误。 But there are other questions, that came up:但还有其他问题,出现了:

1) Has this change other reasons than making the additional definitions useless? 1) 除了使附加定义无用之外,这种变化是否有其他原因? (See also last paragraph of this question) (另见本问题的最后一段)

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. 2) 在cppreference: static members的最后一个示例中,它似乎也适用于const static成员 - 但该规则仅说明了constexpr成员。 Will it apply on const static member or not?它是否适用于const static成员?

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? 3) 我发现的所有例子都使用了一个简单的定义,比如Class::I constexpr它是否也适用于Class:Jconstexpr函数的情况?

A brief state what the best practices are before C++17 and with C++17 would be great.简要说明在 C++17 之前和使用 C++17 的最佳实践是什么会很棒。 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.因此,将生成代码,对于较旧的(17 版之前)编译器,这仍然是“格式错误的非诊断所需” - 但只要不需要 odr-use,这些代码就不会抱怨。

Edit : Corrected the text, suggested by Aaron McDaid.编辑:更正了 Aaron McDaid 建议的文本。

This change is due to the inline variables proposal ( P0386 ).这种变化是由于内联变量提议 ( P0386 )。 static constexpr will imply inline , making definitions redundant. static constexpr将意味着inline ,使定义变得多余。

In Annex D, add a new subclause, “Redeclaration of static constexpr data members”, DX, 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.在附录 D 中,添加新的子条款“静态 constexpr 数据成员的重新声明”DX,内容如下: 为了与先前的 C++ 国际标准兼容,可以在没有初始化程序的类外冗余地重新声明 constexpr 静态数据成员。 This usage is deprecated.此用法已弃用。

[Example: [例子:

 struct A { static constexpr int n = 5; // definition (declaration in C++2014) }; const int A::n; // redundant declaration (definition in C++2014)

—end example] —结束示例]

Regarding to your questions:关于你的问题:

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.这个提议是有争议的,因为它可能鼓励使用可变的全局状态。

Will it apply on const static member or not?它是否适用于const static成员?

No. Unless you annotate it as inline .否。除非您将其注释为inline

does it all hold also for the situation at Class:J with constexpr functions?这是否也适用于Class:Jconstexpr函数的情况?

Yes.是的。 The proposal deals with linking but does not affect initialization rules.该提案处理链接但不影响初始化规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM