繁体   English   中英

C++17 之前/之后的 constexpr 静态成员

[英]constexpr static member before/after C++17

据我所知,一个非常常见的情况是这样的

template<int i> class Class
{
public:
    static constexpr int I = i;
    static constexpr int J = constexprFunction(i);
    // further Class implementation
};

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

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

现在我读了cppreference: Definitions and ODRcppreference: static members ,其中指出,这在 C++17 中已被弃用。 这对我来说似乎很棒,因为它避免了很多错误。 但还有其他问题,出现了:

1) 除了使附加定义无用之外,这种变化是否有其他原因? (另见本问题的最后一段)

2) 在cppreference: static members的最后一个示例中,它似乎也适用于const static成员 - 但该规则仅说明了constexpr成员。 它是否适用于const static成员?

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

简要说明在 C++17 之前和使用 C++17 的最佳实践是什么会很棒。 总而言之,这对我来说似乎是一个非常棘手的变化,因为它会使很多代码,以前“格式错误,不需要诊断”,变成好的代码(据我所知......)。 因此,将生成代码,对于较旧的(17 版之前)编译器,这仍然是“格式错误的非诊断所需” - 但只要不需要 odr-use,这些代码就不会抱怨。

编辑:更正了 Aaron McDaid 建议的文本。

这种变化是由于内联变量提议 ( P0386 )。 static constexpr将意味着inline ,使定义变得多余。

在附录 D 中,添加新的子条款“静态 constexpr 数据成员的重新声明”DX,内容如下: 为了与先前的 C++ 国际标准兼容,可以在没有初始化程序的类外冗余地重新声明 constexpr 静态数据成员。 此用法已弃用。

[例子:

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

—结束示例]

关于你的问题:

除了使附加定义无用之外,这种变化还有其他原因吗?

本质上,没有。 然而,除了您提到的用途之外,它还有其他用途(请参阅此问题)。 这个提议是有争议的,因为它可能鼓励使用可变的全局状态。

它是否适用于const static成员?

否。除非您将其注释为inline

这是否也适用于Class:Jconstexpr函数的情况?

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

暂无
暂无

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

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