简体   繁体   English

g ++和clang ++使用自动参数的模板特化的不同行为

[英]g++ and clang++ different behaviour with template specialization for auto argument

Playing with C++17 auto template arguments I've encountered another g++/clang++ disagreement. 使用C ++ 17 auto模板参数我遇到了另一个g ++ / clang ++分歧。

Given the following simple code 给出以下简单代码

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
 }

I see that clang++ (8.0.0, by example) compile the code where g++ (9.2.0, by example) gives the following error 我看到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;
      |             ^~~

Both compilers compile if we use a int constant instead of a long constant 如果我们使用int常量而不是long常量,两个编译器都会编译

  foo<42>  f42;  // compile with both clang++ and g++

So I have two questions for C++ language layers 所以我对C ++语言层有两个问题

(1) it's legal, in C++17, specialize a template, declared receiving an auto template parameter, for a value of a specific type (as the foo specialization in my code)? (1)在C ++ 17中,对于特定类型的值(作为我的代码中的foo特化),声称接收auto模板参数的模板是专用的吗?

(2) if the answer to the preceding question is "yes", a template specialization can intercept a value of a different (but convertible) type? (2)如果前面问题的答案是“是”,模板专业化可以拦截不同(但可转换)类型的值?

Question (2) is almost: is right clang++ or g++? 问题(2)几乎是:是正确的铿锵++还是g ++?

Here's a slightly different repro that doesn't rely on incomplete types: 这是一个略有不同的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);

This is a clang bug. 这是一个铿锵的错误。 42L clearly matches auto , no question there. 42L清楚地匹配auto ,毫无疑问。 But does it match int I ? 但它与int I匹配吗? No, from [temp.deduct.type]/19 : 不,来自[temp.deduct.type] / 19

If P has a form that contains <i> , and if the type of i differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id , deduction fails. 如果P的表单包含<i> ,并且如果i的类型与封闭的simple-template-id所指定的模板的相应模板参数的类型不同,则扣除失败。 If P has a form that contains [i] , and if the type of i is not an integral type, deduction fails. 如果P具有包含[i]的形式,并且如果i的类型不是整数类型,则推导失败。 [ Example: [ 例如:

 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 } 

end example ] - 结束例子 ]

In order to see if 42L matches the specialization, we need to deduce int I from 42L and that fails. 为了查看42L与特化相匹配,我们需要从42L 推导出 int I并且失败。 Hence, we stick with the primary specialization. 因此,我们坚持主要专业化。 clang does not do this. clang不这样做。 Filed 43076 . 提起43076

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 g ++和clang ++不同的行为推导可变参数模板`auto`值 - g++ and clang++ different behaviour deducing variadic template `auto` values g ++和clang ++使用变量模板和SFINAE的不同行为 - g++ and clang++ different behaviour with variable template and SFINAE g ++和clang ++使用指向可变参数模板函数的指针的不同行为 - g++ and clang++ different behaviour with pointer to variadic template functions 带有集成模板参数的g ++和clang ++不同的行为 - g++ and clang++ different behaviour with integral template parameter g ++和clang ++在模板类中定义的朋友模板函数的不同行为 - g++ and clang++ different behaviour with friend template function defined inside a template class g ++和clang ++不同的行为推断函数的模板返回类型 - g++ and clang++ different behaviour inferring the template return type of a function g ++和clang ++使用静态成员的递归初始化的不同行为 - g++ and clang++ different behaviour with recursive initialization of a static member g ++和clang ++使用运算符&lt;()重载的不同行为 - g++ and clang++ different behaviour with operator<() overloading g++ 和 clang++ 与可变参数容器的不同行为 - g++ and clang++ different behaviour with variadic container g ++和clang ++与流输入和无符号整数的不同行为 - g++ and clang++ different behaviour with stream input and unsigned integer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM