static constinit 成员变量是否与非类型模板参数相同?
Are static constinit member variables identical to non-type template parameters?
我有一个 N 维数组的 class 模板:
template<typename T, std::size_t... Shape>
class ndarray { ... };
此模板设计的一个结果是,如果您愿意,还有一个额外的 'implicit' 模板参数:std::size_t Size
,Shape
中所有参数的乘积。我一直在使用 C++17 折叠表达式 ((1 * ... * Shape)
),如果它不依赖于 Shape
,我通常会使用 Size
,但我想知道是否添加以下内容'alias' 会导致编译后的程序集出现任何细微差异:
template<typename T, std::size_t... Shape>
class ndarray {
static constinit std::size_t Size = (1 * ... * Shape);
...
};
有趣的是,ISO C++20 标准并没有像 constexpr
和 consteval
那样说明 constinit
是否意味着 inline
。我认为 constinit
的语义(尤其是与 constexpr
变量相关的语义)只有在变量也是 inline
时才真正有意义,但它在标准中的遗漏让我对这个结论持谨慎态度。
constinit
和只有一个语义:用于初始化变量的表达式必须是常量表达式。
就是这样。这就是它所做的全部:如果初始化表达式不是有效的常量表达式,它会导致编译错误。在其他方式中,这样的变量等同于没有constinit
。事实上,该提案的早期版本将 constinit 作为属性而不是关键字,因为它实际上 做 没有任何作用。它只给出了变量初始化无效的编译错误。
对于这种情况,没有理由不使变量constexpr
。您显然不打算更改变量,因此没有必要使变量可修改。
不,它们根本不一样,因为 constinit
没有生成变量 const
。因此,Size
的初始化甚至 无效 。写作 constinit const
基本上等同于写作 constexpr
,后者在语义上 等价于 常量 fold-expression。不能保证任何编译器都会以相同的方式对待它们,但在大多数常量表达式情况下,变化的空间不大。
constinit
也不代表inline
:不是标准“不说是否”,只是无话可说。由于将 constinit
和 constexpr
放在同一个变量上没有意义,因此不清楚您在该区域期望的语义。
我有一个 N 维数组的 class 模板:
template<typename T, std::size_t... Shape>
class ndarray { ... };
此模板设计的一个结果是,如果您愿意,还有一个额外的 'implicit' 模板参数:std::size_t Size
,Shape
中所有参数的乘积。我一直在使用 C++17 折叠表达式 ((1 * ... * Shape)
),如果它不依赖于 Shape
,我通常会使用 Size
,但我想知道是否添加以下内容'alias' 会导致编译后的程序集出现任何细微差异:
template<typename T, std::size_t... Shape>
class ndarray {
static constinit std::size_t Size = (1 * ... * Shape);
...
};
有趣的是,ISO C++20 标准并没有像 constexpr
和 consteval
那样说明 constinit
是否意味着 inline
。我认为 constinit
的语义(尤其是与 constexpr
变量相关的语义)只有在变量也是 inline
时才真正有意义,但它在标准中的遗漏让我对这个结论持谨慎态度。
constinit
和只有一个语义:用于初始化变量的表达式必须是常量表达式。
就是这样。这就是它所做的全部:如果初始化表达式不是有效的常量表达式,它会导致编译错误。在其他方式中,这样的变量等同于没有constinit
。事实上,该提案的早期版本将 constinit 作为属性而不是关键字,因为它实际上 做 没有任何作用。它只给出了变量初始化无效的编译错误。
对于这种情况,没有理由不使变量constexpr
。您显然不打算更改变量,因此没有必要使变量可修改。
不,它们根本不一样,因为 constinit
没有生成变量 const
。因此,Size
的初始化甚至 无效 。写作 constinit const
基本上等同于写作 constexpr
,后者在语义上 等价于 常量 fold-expression。不能保证任何编译器都会以相同的方式对待它们,但在大多数常量表达式情况下,变化的空间不大。
constinit
也不代表inline
:不是标准“不说是否”,只是无话可说。由于将 constinit
和 constexpr
放在同一个变量上没有意义,因此不清楚您在该区域期望的语义。