我的印象是以下内容应该成为新的 C++20 标准下的有效代码:
struct Foo
{
int a, b;
};
template<Foo>
struct Bar
{};
Bar<{.a=1, .b=2}> bar;
Run Code Online (Sandbox Code Playgroud)
然而,gcc 10.2.0
,-std=c++20
设置抱怨:could not convert ‘{1, 2}’ from ‘<brace-enclosed initializer list>’ to ‘Foo’
和 Clang 也不能编译这个片段。有人可以指出为什么它没有很好地形成吗?
我有这门课
template <typename ValueType, std::size_t Size>
struct ArrayPrimitive
{
constexpr ArrayPrimitive(const ValueType (&array)[Size]) {
std::copy(array, array + Size, data_);
}
ValueType data_[Size];
};
Run Code Online (Sandbox Code Playgroud)
这是我尝试将字符串文字传递为 NTTP 的包装器。然后我利用 CTAD 声明这个变量模板
template <ArrayPrimitive array>
std::integral_constant<decltype(array), array> arr;
Run Code Online (Sandbox Code Playgroud)
然后在代码中使用它
for (auto i : arr<{{2,4,6}}>.value.data_) std::cout << i << std::endl;
它编译并正确打印所有值。
我使用的编译器是 gcc13.2,我知道它目前无法在 clang 上运行,因为 c++20 对 NTTP 类的支持还不存在。另外,VS Code 的代码分析器确实不喜欢模板实例化中的括号,这有点奇怪,因为它没有arr<"123">
.
我想知道它是否符合标准并且不会因未来的变化而中断。
编辑:查看错误报告GCC bug 111277的答案,看来 GCC 确实实现了 CWG 2450,将其置于预期行为领域,但仅适用于这一个编译器。
EDIT2:如果我这样写的话,它似乎也可以用 MSVC 编译https://gcc.godbolt.org/z/1sThrse3x
c++ template-meta-programming c++20 ctad non-type-template-parameter