偏特化的默认参数 [Clang yes, GCC no]
Default argument for partial specialization [Clang yes, GCC no]
为什么下面的代码用 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;
}
http://coliru.stacked-crooked.com/a/c7800f49ba5aac43
g++ 没有找到合适的专业并抱怨 "incomplete type"。我想知道,默认参数 typename T3 = int
应该适用于专业化(或者它只适用于完全专业化?)
模板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;
}
另一个更简单的专业化的好例子:
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;
}
就像@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;
}
为什么下面的代码用 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;
}
http://coliru.stacked-crooked.com/a/c7800f49ba5aac43
g++ 没有找到合适的专业并抱怨 "incomplete type"。我想知道,默认参数 typename T3 = int
应该适用于专业化(或者它只适用于完全专业化?)
模板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;
}
另一个更简单的专业化的好例子:
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;
}
就像@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;
}