【问题标题】:Are static constinit member variables identical to non-type template parameters?静态 constinit 成员变量是否与非类型模板参数相同?
【发布时间】:2021-11-09 06:59:00
【问题描述】:

我有一个 N 维数组的类模板:

template<typename T, std::size_t... Shape>
class ndarray { ... };

这种模板设计的一个结果是,如果您愿意,还有一个额外的“隐式”模板参数:std::size_t SizeShape 中所有参数的乘积。我一直在使用 C++17 折叠表达式 ((1 * ... * Shape)),如果它不依赖于 Shape,我通常会使用 Size,但我想知道添加以下“别名”是否会导致编译程序集的任何细微差别:

template<typename T, std::size_t... Shape>
class ndarray {
    static constinit std::size_t Size = (1 * ... * Shape);
    ...
};

有趣的是,ISO C++20 标准没有说明constinit 是否暗示inline,就像它对constexprconsteval 所做的那样。我认为constinit 的语义(尤其是与constexpr 变量相关的)只有在变量也是inline 时才真正有意义,但它在标准中的遗漏让我对这个结论保持警惕。

【问题讨论】:

  • 为什么要将它设为constinit 变量而不是constexpr?以后打算修改吗?
  • @NicolBolas 哇!你的评论让我又看了constinit,一开始我完全误解了。

标签: c++ language-lawyer c++20


【解决方案1】:

constinit 具有完全相同且一种语义:用于初始化变量的表达式必须是常量表达式。

就是这样。这就是它所做的一切:如果初始化表达式不是有效的常量表达式,它会导致编译错误。在其他方式中,这样的变量等同于没有constinit。事实上,该提案的早期版本将 constinit 作为属性而不是关键字,因为它并没有真正任何事情。它只是对变量的无效初始化给出了编译错误。

对于这种情况,没有理由不创建变量constexpr。您显然不打算更改变量,因此使变量可修改是没有意义的。

【讨论】:

    【解决方案2】:

    不,这些根本不一样,因为constinit 不会生成变量const。因此,Size 的初始化甚至不是有效。写constinit const 大部分等同于写constexpr,在语义上等价 到常量fold-expression。无法保证任何编译器都会对它们一视同仁,但在大多数常量表达式的情况下,变化空间不大。

    constinit 也不暗示inline:不是标准“没有说明是否”,只是无话可说。由于将constinitconstexpr 放在同一个变量上是没有意义的,因此不清楚您在该区域中期望什么语义。

    【讨论】:

      猜你喜欢
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多