【问题标题】:Does redeclaring a static const member as constexpr automatically qualify it to be inline?将静态 const 成员重新声明为 constexpr 是否会自动将其限定为内联?
【发布时间】:2017-10-11 06:29:49
【问题描述】:

考虑static constexpr 成员的这个用例:

// smart_enum.h
class smart_enum {
    // Some data, operations, etc.
    // Cannot use constexpr here, smart_enum is incomplete at this point
    static const smart_enum first, second;
};

constexpr smart_enum smart_enum::first = {}, smart_enum::second = {};

firstsecond 是否自动成为 inline 变量?还是我需要对它们进行资格认证?还是我无法将它们限定为内联并且需要稍后在某些源文件中提供定义?我一直对这种从 constconstexpr 的“重新定义”感到困惑,并希望能更清楚地了解这究竟意味着什么。

具体来说,我想知道const 声明与constexpr 定义之间的交互,以及它如何与static constexpr (Redefinitions of constexpr static data members are allowed now? (but not inline const)?) 的自动inline 相互作用

【问题讨论】:

  • “此外,​constexpr​ 说明符意味着静态数据成员和函数的内联。” - 但是我会把那个 constexpr 放在我认为的类中。
  • @lorro 但你不能把它放在课堂上,这就是我困惑的根源。

标签: c++ c++17 constexpr


【解决方案1】:

标准说:

[c++17-12.2.3.2-2]在其类定义中声明非内联静态数据成员不是定义,可能是cv void以外的不完整类型。

现在,也许你的困惑源于相信这两个表达方式

static const smart_enum first; // class scope
constexpr smart_enum smart_enum::first = ...; // namespace scope

声明不同的类型。情况并非如此,因为constexpr T 的类型仍然是const T(实际上您可以始终写成constexpr const T 来表示相同的意思)。

因此,在您的代码中,您首先声明一个不完整类型“const smart_enum”的名称“first”,然后将其定义为“constexpr smart_enum”(或“constexpr inline const smart_enum”如果我们添加所有 constexpr 显式暗示的内容)。

【讨论】:

    【解决方案2】:

    当然,在 C++14 中,没有变量是内联的。使这样的变量自动内联是一个无意的破坏更改(因为这意味着定义必须出现在每个翻译单元中)。我提交了CWG2531 试图纠正这个问题。现在当然存在 C++17 实现的向后兼容性问题,尽管任何想要其他行为的代码都可以将 inline 添加到已经允许的类外定义中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      相关资源
      最近更新 更多