C ++ 17之前/之后的constexpr静态成员 [英] constexpr static member before/after C++17

查看:68
本文介绍了C ++ 17之前/之后的constexpr静态成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,一种非常常见的情况是

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 with constexpr functions?

是。该提案处理链接,但不影响初始化规则。

Yes. The proposal deals with linking but does not affect initialization rules.

这篇关于C ++ 17之前/之后的constexpr静态成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆