在上一篇文章中,我讨论了一种从非类型模板参数创建静态值的技术。
在这篇文章及其接受的答案中,给出了实现此目标的代码,但在某些情况下无法使用 msvc 进行编译。
下面给出一个最小的例子:
#include <type_traits>
template <class T>
struct value_holder {
T value;
};
template <auto V>
constexpr auto const& make_static() {
if constexpr (std::is_class_v<decltype(V)>) {
return V;
} else {
return make_static<value_holder{V}>().value;
}
}
int main() {
[[maybe_unused]] constinit static const auto v = make_static<2>();
[[maybe_unused]] constinit static const auto& r = make_static<2>();
return v;
}
虽然 gcc 和 clang 接受此代码,但 msvc 输出为:
error C2127: 'r': illegal initialization of 'constinit' entity with a non-constant expression
在 msvc 19.40 之前,行为是相同的。
这是一个 msvc 错误吗?
这是一个 MSVC 错误。
A 常量表达式 是泛左值核心常量表达式,它引用作为常量表达式允许结果的实体 [...] 实体是常量表达式的允许结果如果它是具有静态存储持续时间的对象
命名类类型
T
的非类型 template-parameter 的id-expression表示类型的静态存储持续时间对象,称为 模板参数对象const T
这似乎是一个专门针对
constinit
引用的错误。作为解决方法,请改用指针。