max*_*x66 11 c++ template-specialization language-lawyer auto c++17
在使用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
}
Run Code Online (Sandbox Code Playgroud)
我看到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;
| ^~~
Run Code Online (Sandbox Code Playgroud)
如果我们使用int常量而不是long常量,则两个编译器都将编译
foo<42> f42; // compile with both clang++ and g++
Run Code Online (Sandbox Code Playgroud)
所以我对C ++语言层有两个问题
(1)在C ++ 17中,auto针对特定类型的值(如foo我的代码中的专门化),对声明接收了模板参数的模板进行专门化是合法的吗?
(2)如果对上一个问题的答案为“是”,则模板专业化可以拦截其他(但可转换)类型的值吗?
问题(2)几乎是:是clang ++还是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);
Run Code Online (Sandbox Code Playgroud)
这是一个lang虫。42L显然匹配auto,没有问题。但这匹配int I吗?不,来自[temp.deduct.type] / 19:
如果
P具有包含的形式<i>,并且如果的类型i不同于由随附的simple-template-id命名的模板的相应模板参数的类型,则推论失败。如果P具有包含的形式[i],并且类型i为非整数,则推论失败。[ 示例:Run Code Online (Sandbox Code Playgroud)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与专业匹配,我们需要从中推论 int I出42L,但失败了。因此,我们坚持主要的专业化。lang不这样做。提起43076。
| 归档时间: |
|
| 查看次数: |
128 次 |
| 最近记录: |