非类型模板参数不能具有类型 [英] a non-type template parameter cannot have type

查看:82
本文介绍了非类型模板参数不能具有类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于将来遇到这个问题的人来说,原始问题是:如何从此

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尚未将类类型实现为非类型模板参数,请参见

    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆