c++ - 是否允许在模板特化时从 int 转换为 long (此代码应该编译)?

标签 c++ language-lawyer

看看这个片段:

template <long>
struct Bar { };

template <typename>
struct Foo;

template <int X>
struct Foo<Bar<X>> { };

Foo<Bar<0>> x;

Barlong参数,但是Fooint 。 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]

  1. A template-argument matches a template template-parameter P when P is at least as specialized as the template-argument A. If P contains a parameter pack, then A also matches P if each of A’s template parameters matches the corresponding template parameter in the template-parameter-list of P. 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]

  1. Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one-definition rule (3.2)

所以自从替换 intlong函数定义中将不满足单一定义规则模板参数将不匹配且 Foo不会选择专业。

  • 对于模板函数:

14.8.2.5 Deducing template arguments from a type [temp.deduct.type]

  1. 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. If P has a form that contains [i], and if the type of i 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/

相关文章:

c++ - OpenCV Mat 数据结构

c++ - 杀死具有套接字的单独线程

c++ - 默认构造函数表达式和左值

c - GCC 11.2.0 或 Apple Clang 13.0.0 (clang-1300.0.29.30) 关于应用于 VLA 参数的 const 是否正确?

c++ - 是一个 typedef 到 self 允许在模板参数上

c++ - 为类型特征排序多个 std::void_t 部分特化的可靠方法

c++ - 动态添加QWebEngineView到布局

c++ - 为什么在写入不够大的 malloc 内存时 strcpy "work"?

c++ - 使标题看起来像是在不同的文件夹中

c++ - 什么时候私有(private)构造函数不是私有(private)构造函数?