Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否允许在模板专门化时从int转换为long(这段代码应该编译)?_C++_Language Lawyer - Fatal编程技术网

C++ 是否允许在模板专门化时从int转换为long(这段代码应该编译)?

C++ 是否允许在模板专门化时从int转换为long(这段代码应该编译)?,c++,language-lawyer,C++,Language Lawyer,请看这个片段: template <long> struct Bar { }; template <typename> struct Foo; template <int X> struct Foo<Bar<X>> { }; Foo<Bar<0>> x; 哪个编译器是正确的?据我所知,这些部分的推导应该失败: 对于模板类: 14.3.3模板参数[临时参数模板] 当P至少与模板参数A一样专用时,模板参数

请看这个片段:

template <long>
struct Bar { };

template <typename>
struct Foo;

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

Foo<Bar<0>> x;

哪个编译器是正确的?

据我所知,这些部分的推导应该失败:

  • 对于模板类:
14.3.3模板参数[临时参数模板]

  • P
    至少与模板参数
    A
    一样专用时,模板参数与模板参数
    P
    匹配。如果
    P
    包含一个参数包,那么
    a
    如果
    a
    的每个模板参数都与
    P
    的模板参数列表中相应的模板参数匹配,那么
    a也会匹配
    P
    。如果两个模板参数属于同一类型(类型、非类型、模板),则两个模板参数匹配,对于非类型模板参数,它们的类型是等效的(14.5.6.1),对于模板模板参数,每个对应的模板参数递归匹配
  • 等价性定义为:

    14.5.6.1函数模板重载[temp.over.link]

  • 如果包含模板参数的两个函数定义满足一个定义规则(3.2),则认为两个表达式是等效的
  • 因此,由于在函数定义中用
    long
    替换
    int
    将不满足一个定义规则,因此模板参数将不匹配,并且不会选择
    Foo
    专门化

    • 对于模板函数:
    14.8.2.5从类型[temp.deletry.type]推断模板参数

  • 如果
    P
    具有包含
    的表单,并且如果
    i
    的类型与随附的简单模板id命名的模板的相应模板参数的类型不同,则扣减失败。如果
    P
    的表单包含
    [i]
    ,并且
    i
    的类型不是整数类型,则扣减失败
  • 模板类A{/*…*/};
    模板f(A);
    无效k1(){
    A A;
    f(a);//错误:从int到short的转换中扣除失败
    f(a);//好的
    }
    
    好的,很公平。@rici问题是这个错误是否应该首先出现。这就是是否应该选择完整的Foo专门化,即使非类型模板参数的类型不同。(不小心删除了评论)@vtt:是的,我读过了,现在我得到了,所以我故意删除了我的评论。对不起,吵闹了。Hvd的dup非常清楚。@rici事实上你发表了正确的评论,因为我的问题最初包含了标准错误部分的引用。而那个被用作亲密理由的问题也包含了同样的引语。
    error: aggregate ‘Foo<Bar<0> > x’ has incomplete type and cannot be defined
    
    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
    }