[英]g++ and clang++ different behaviour deducing variadic template `auto` values
[英]g++ and clang++ different behaviour with template specialization for auto argument
使用C ++ 17 auto
模板参数我遇到了另一个g ++ / clang ++分歧。
给出以下简单代码
template <auto>
struct foo;
template <int I>
struct foo<I>
{ };
int main ()
{
foo<42l> f42; // <--- long constant, not int constant
(void)f42; // avoid the "unused variable" warning
}
我看到clang ++(8.0.0,通过示例)编译代码,其中g ++(9.2.0,通过示例)给出以下错误
prog.cc: In function 'int main()':
prog.cc:12:13: error: aggregate 'foo<42> f42' has incomplete type and cannot be defined
12 | foo<42l> f42;
| ^~~
如果我们使用int
常量而不是long
常量,两个编译器都会编译
foo<42> f42; // compile with both clang++ and g++
所以我对C ++语言层有两个问题
(1)在C ++ 17中,对于特定类型的值(作为我的代码中的foo
特化),声称接收auto
模板参数的模板是专用的吗?
(2)如果前面问题的答案是“是”,模板专业化可以拦截不同(但可转换)类型的值?
问题(2)几乎是:是正确的铿锵++还是g ++?
这是一个略有不同的repro,不依赖于不完整的类型:
template <auto> struct foo { static constexpr int value = 0; };
template <int I> struct foo<I> { static constexpr int value = 1; };
// ok on gcc, fires on clang which thinks foo<42L>::value is 1
static_assert(foo<42L>::value == 0);
这是一个铿锵的错误。 42L
清楚地匹配auto
,毫无疑问。 但它与int I
匹配吗? 不,来自[temp.deduct.type] / 19 :
如果
P
的表单包含<i>
,并且如果i
的类型与封闭的simple-template-id所指定的模板的相应模板参数的类型不同,则扣除失败。 如果P
具有包含[i]
的形式,并且如果i
的类型不是整数类型,则推导失败。 [ 例如:template<int i> class A { /* ... */ }; template<short s> void f(A<s>); void k1() { A<1> a; f(a); // error: deduction fails for conversion from int to short f<1>(a); // OK } template<const short cs> class B { }; template<short s> void g(B<s>); void k2() { B<1> b; g(b); // OK: cv-qualifiers are ignored on template parameter types }
- 结束例子 ]
为了查看42L
与特化相匹配,我们需要从42L
推导出 int I
并且失败。 因此,我们坚持主要专业化。 clang不这样做。 提起43076 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.