非类型模板参数不能具有类型 [英] a non-type template parameter cannot have type
问题描述
For anyone stumbling upon this question in the future, the original question was: "How to get the simplest example (Point) from this article to compile with GCC or CLANG?"
- 编辑1显示了可能的最小代码,这些代码在CLANG中失败,但是在GCC中都可以编译(均为-std = c ++ 2a).
- 编辑2显示了添加的其他代码,这些代码也破坏了GCC.
该文章的作者( @BarryRevzin )对此发表了足够的评论.,谢谢巴里!
The author of the article (@BarryRevzin) was kind enough to comment the reason why this won't work yet, thank you Barry!
下面的简化代码适用于gcc 9.3.0,但不适用于clang 10.0.0:
Simplified code below works with gcc 9.3.0 but not with clang 10.0.0:
struct Point {
int x = 0;
int y = 0;
};
template <Point> // ok in C++20
void takes_tmpl_point();
int main()
{
// EMPTY
}
根据作者的说法,由于编译器稍稍落后于标准,原始代码目前仍无法在GCC或CLANG上运行.下面的原始代码:
Edit 2:
The original code, as per the author, won't work on GCC or CLANG as of yet due to the compilers being behind the standard a bit. Original code below:
struct Point {
int x = 0;
int y = 0;
};
template <Point> // ok in C++20
void takes_tmpl_point();
int main()
{
takes_tmpl_point<{.x=1, .y=2}>(); // x=1, y=2
}
这将在GCC 9.3上导致以下编译错误:
This will result in the following compilation error on GCC 9.3:
test.cpp: In function ‘int main()’:
test.cpp:11:35: error: no matching function for call to ‘takes_tmpl_point<{1, 2}>()’
11 | takes_tmpl_point<{.x=1, .y=2}>(); // x=1, y=2
| ^
test.cpp:7:6: note: candidate: ‘template<Point <anonymous> > void takes_tmpl_point()’
7 | void takes_tmpl_point();
| ^~~~~~~~~~~~~~~~
test.cpp:7:6: note: template argument deduction/substitution failed:
test.cpp:11:35: error: could not convert ‘{1, 2}’ from ‘<brace-enclosed initializer list>’ to ‘Point’
11 | takes_tmpl_point<{.x=1, .y=2}>(); // x=1, y=2
| ^
还有clang 10.0.0的以下错误:
And the following error on clang 10.0.0:
test.cpp:6:16: error: a non-type template parameter cannot have type 'Point'
template <Point> // ok in C++20
^
test.cpp:11:21: error: expected expression
takes_tmpl_point<{.x=1, .y=2}>(); // x=1, y=2
^
2 errors generated.
使用的编译器:
- clang:clang版本10.0.0-4ubuntu1
- gcc:gcc(Ubuntu 9.3.0-10ubuntu2)9.3.0
推荐答案
Clang just doesn't implement class types as non-type template parameters yet, see P1907 in this table.
gcc确实实现了它们,但实际上这里存在一个问题. template-argument 实际上不允许使用 braced-init-list .这是一个明显的语言缺陷(在 P1907 之前从来没有理由拥有这样的东西,但是现在肯定没有不拥有它的原因).目前,这是一个语言错误.尽管如此,gcc还是继续支持 braced-init-list 作为模板参数...只是不支持 designated-initializer-list .
gcc does implement them but there's actually an issue here. The grammar for template-argument doesn't actually allow for a braced-init-list. This is a clear language defect (there was never a reason to have such a thing before P1907 but now there's certainly no reason to not have it). This is a language bug at the moment. Nevertheless, gcc went ahead and does support a braced-init-list as a template argument... just not a designated-initializer-list.
因此,我的博客文章比实际语言要领先一点……直到该语言流行为止,即使在技术上不受支持:
So that blog post of mine is running ahead of the actual language by a bit... Until the language catches up, even though this is technically unsupported:
takes_tmpl_point<{.x=1, .y=2}>();
这绝对是有效的:
takes_tmpl_point<Point{.x=1, .y=2}>();
这篇关于非类型模板参数不能具有类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!