c++ 积分非类型参数和非积分非类型的模板部分专业化,g和clang之间的差异

以下是一个简单的模板部分专业化:

// #1
template <typename T, T n1, T n2>
struct foo { 
    static const char* scenario() {
        return "#1 the base template";
    }
};

// #2
// partial specialization where T is unknown and n1 == n2
template <typename T, T a>
struct foo<T, a, a> { 
    static const char* scenario() {
        return "#2 partial specialization";
    }
};

以下主要对g(6.1)和cl(3.8.0)得到不同的结果:

extern const char HELLO[] = "hello";
double d = 2.3;

int main() {
    cout <<   foo<int, 1, 2>                    ::scenario() << endl;                   
    cout <<   foo<int, 2, 2>                    ::scenario() << endl;                   
    cout <<   foo<long, 3, 3>                   ::scenario() << endl;                  
    cout <<   foo<double&, d, d>                ::scenario() << endl;               
    cout <<   foo<double*, &d, &d>              ::scenario() << endl;             
    cout <<   foo<double*, nullptr, nullptr>    ::scenario() << endl;   
    cout <<   foo<int*, nullptr, nullptr>       ::scenario() << endl;      
    cout <<   foo<nullptr_t, nullptr, nullptr>  ::scenario() << endl; 
    cout <<   foo<const char*, HELLO, HELLO>    ::scenario() << endl;
}

结果在g和clang

#|代码| g(6.1)| cl ang(3.8.0)|
1 | foo< int,1,2> | #1如预期| #1如预期|
2 | foo< int,2> 2> | #2如预期| #2如预期|
3 | foo< long,3,3> | #2如预期| #2如预期|
4 | foo< double& d,d> | #1 – 为什么? | #2如预期|
5 | foo< double *,& d& d> | #2如预期| #2如预期|
6 | foo< double *,nullptr,nullptr> | #2如预期| #1 – 为什么|
7 | foo< int *,nullptr,nullptr> | #2如预期| #1 – 为什么? |
8 | foo< nullptr_t,nullptr,nullptr> | #2如预期| #1 – 为什么? |
9 | foo< const char *,HELLO,HELLO> | #2如预期| #2如预期|

哪一个是对的?

代码:http://coliru.stacked-crooked.com/a/45ba16c9f021fd84

最佳答案
我认为在clang nullptr更像是内建变量,像内置类型int。 nullptr实际上没有类型。 nullptr_t的声明(没有定义)是struct nullptr_t nullptr_t ;.对于正确的问题的答案…答案是两个都是正确的,因为有标准,但这些是由不同公司制作的不同的编译器,所以GNU G和Clang之间可能有差异。 Clang应该与G完全兼容,但不是。

转载注明原文:c++ 积分非类型参数和非积分非类型的模板部分专业化,g和clang之间的差异 - 代码日志