我有以下模板:
template<typename T, typename S=void>
struct Array;
template<typename T, int N0, int N1, int S0, int S1>
struct Array<T[N0][N1], T[S0][S1]> {};
template<typename T, int N0, int N1>
struct Array<T[N0][N1], void> : Array<T[N0][N1], T[N1][1]> {};
template<typename T, int N0, int N1, int N2, int S0, int S1, int S2>
struct Array<T[N0][N1][N2], T[S0][S1][S2]> {
template<int B0, int E0, int B1, int E1, int B2, int E2>
Array<T[E0 - B0][E1 - B1][E2 - B2], T[S0][S1][S2]>
get() {
return Array<T[E0 - B0][E1 - B1][E2 - B2], T[S0][S1][S2]>();
}
};
template<typename T, int N0, int N1, int N2>
struct Array<T[N0][N1][N2], void> : Array<T[N0][N1][N2], T[N1 * N2][N2][1]> {};
int main() {
Array<float[3][4][4], float[16][4][1]> a;
auto b = a.get<0, 2, 0, 2, 0, 1>();
return 0;
}
由于模板的模糊部分特化,我收到以下错误:
$ clang++ -std=c++11 main.cpp && ./a.out
main.cpp:26:14: error: ambiguous partial specializations of 'Array<float [2][2][1], float [16][4][1]>'
auto b = a.get<0, 2, 0, 2, 0, 1>();
^
main.cpp:5:8: note: partial specialization matches [with T = float [1], N0 = 2, N1 = 2, S0 = 16, S1 = 4]
struct Array<T[N0][N1], T[S0][S1]> {};
^
main.cpp:11:8: note: partial specialization matches [with T = float, N0 = 2, N1 = 2, N2 = 1, S0 = 16, S1 = 4, S2 = 1]
struct Array<T[N0][N1][N2], T[S0][S1][S2]> {
^
1 error generated.
有没有办法可以避免这种歧义?换句话说,我希望只有当T是非数组类型时,Array模板才有效。
答案 0 :(得分:4)
可能有点矫枉过正,但你可以强迫T
不成为数组:
#include <type_traits>
template<typename T, typename S = void, typename Dummy = void>
struct Array;
template<typename T, int N0, int N1, int S0, int S1>
struct Array<T[N0][N1],
T[S0][S1],
typename std::enable_if<!std::is_array<T>::value>::type>
{ };
template<typename T, int N0, int N1>
struct Array<T[N0][N1],
void,
typename std::enable_if<!std::is_array<T>::value>::type>
: Array<T[N0][N1], T[N1][1]>
{ };
template<typename T, int N0, int N1, int N2, int S0, int S1, int S2>
struct Array<T[N0][N1][N2],
T[S0][S1][S2],
typename std::enable_if<!std::is_array<T>::value>::type>
{
template<int B0, int E0, int B1, int E1, int B2, int E2>
Array<T[E0 - B0][E1 - B1][E2 - B2], T[S0][S1][S2]>
get()
{
return {};
}
};
如果您确实想要允许T
的数组类型,则需要对其进行更多处理。