部分特化的默认参数[Clang yes,GCC no]

Gab*_*iel 14 c++ gcc clang template-specialization c++11

为什么以下编译clang但不编译g++ 4.9

#include <array>

template< typename T1, typename T2 , typename T3 = int>
struct A;

template<typename T, unsigned int N, typename T2, typename T3>
struct A< std::array<T,N>, T2,  T3 > {
    int a;
};

int main()
{
  A< std::array<int,10>, double>  a;
  a.a +=3;
}
Run Code Online (Sandbox Code Playgroud)

http://coliru.stacked-crooked.com/a/c7800f49ba5aac43

g ++没有找到合适的专业化并抱怨"不完整类型".我想知道,因为默认参数typename T3 = int应该适用于专业化(或者它是否只适用于完全专业化?)

Dav*_*ujo 4

模板A<T1, T2, T3>A<T1, T2>完整定义,因此您无法使用您的成员,您可以通过以下方式解决定义此模板的问题:

#include <array>

template< typename T1, typename T2 , typename T3 = int>
struct A {
    int a;
};

template<typename T, unsigned int N, typename T2, typename T3>
struct A< std::array<T,N>, T2,  T3 > {
    int a;
};

int main()
{
    A< std::array<int,10>, double>  a;
    a.a +=3;
}
Run Code Online (Sandbox Code Playgroud)

另一个更简单的专业化的好例子:

template<typename T, unsigned int N>
struct A {
    T a = N;
};

template<unsigned int N>
struct A<int, N> {
    int a = 2*N;
};

#include <iostream>
using namespace std;

main() {
    A<float, 30> af;
    A<int, 30> ai;
    cout << af.a << endl << ai.a << endl;
}
Run Code Online (Sandbox Code Playgroud)

就像@dys 在你的评论中所说的那样,使用std::size_t相反的unsigned int方法:

template< typename T1, typename T2 , typename T3 = int>
struct A;

template<typename T, std::size_t N, typename T2, typename T3>
struct A< std::array<T,N>, T2,  T3 > { 
        T3 a = N;
        int b; 
};

int main()
{
        A< std::array<int,10>, double>  a;
        a.a +=3;

        A< std::array<int,10>, double, int>  b;
        b.b +=3;
}
Run Code Online (Sandbox Code Playgroud)