看看这个片段:
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 编译了这个,但 GCC-6/7/8 没有:
error: aggregate ‘Foo<Bar<0> > x’ has incomplete type and cannot be defined
哪个编译器是正确的?
最佳答案
据我了解,这些部分推导应该失败:
- 对于模板类:
14.3.3 Template template arguments [temp.arg.template]
- A template-argument matches a template template-parameter
P
whenP
is at least as specialized as the template-argumentA
. IfP
contains a parameter pack, thenA
also matchesP
if each ofA
’s template parameters matches the corresponding template parameter in the template-parameter-list ofP
. Two template parameters match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are equivalent (14.5.6.1), and for template template-parameters, each of their corresponding template-parameters matches, recursively.
等价定义为:
14.5.6.1 Function template overloading [temp.over.link]
- Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one-definition rule (3.2)
所以自从替换 int
与 long
函数定义中将不满足单一定义规则模板参数将不匹配且 Foo
不会选择专业。
- 对于模板函数:
14.8.2.5 Deducing template arguments from a type [temp.deduct.type]
- If
P
has a form that contains<i>
, and if the type ofi
differs from the type of the corresponding template parameter of the template named by the enclosing simple-template-id, deduction fails. IfP
has a form that contains[i]
, and if the type ofi
is not an integral type, deduction fails.
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
}
关于c++ - 是否允许在模板特化时从 int 转换为 long (此代码应该编译)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47111131/