看看这个片段:
template <long>
struct Bar { };
template <typename>
struct Foo;
template <int X>
struct Foo<Bar<X>> { };
Foo<Bar<0>> x;Bar有long参数,但是Foo有int。Clang-4/5/6 /6编译,但GCC-6/7/8没有:
error: aggregate ‘Foo<Bar<0> > x’ has incomplete type and cannot be defined哪个编译器是正确的?
发布于 2017-11-04 13:27:25
据我所知,这些部分的扣减应该失败:
14.3.3模板参数temp.arg.template
P时,P至少与模板参数A一样专门化。如果P包含一个参数包,那么如果A的每个模板参数与P的模板参数列表中的相应模板参数匹配,那么A也匹配P。如果两个模板参数是相同类型的(类型、非类型、模板),则匹配两个模板参数,对于非类型模板参数,它们的类型是等效的 (14.5.6.1),对于模板参数,它们各自对应的模板参数匹配,递归。等值的定义是:
14.5.6.1函数模板重载temp.over.link
因此,由于函数定义中用int替换long将不能满足单定义规则,模板参数将不匹配,而Foo专门化也不会被选择。
14.8.2.5从类型temp.deduct.type推导模板参数
P有一个包含<i>的表单,并且如果i类型与封装简单模板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
}https://stackoverflow.com/questions/47111131
复制相似问题