Шаблонный метод специализации шаблона
Вот мой код:
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
Это хорошо работает. Но когда я пытаюсь добавить этот
template<typename T1, typename T2> template<> int MyClass<T1, T2>::DoSomething<0>()
{
cout << "This is ZERO!!!" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
Я получаю ошибки компилятора:
недопустимая явная специализация перед токеном " > "
template-id "DoSomething < 0 > " для "int MyClass:: DoSomething()" не соответствует объявлению шаблона
Я использую g++ 4.6.1
Что мне делать?
Ответы
Ответ 1
К сожалению, вы не можете специализировать шаблон, являющийся членом шаблона класса, не специализируясь на внешнем шаблоне:
С++ 11 14.7.3/16: В явном объявлении специализации для члена шаблона класса или шаблона-члена, который появляется в области пространства имен, шаблон-член и некоторые из его вмещающих шаблонов классов могут оставаться неспециализированными, , за исключением того, что объявление не должно явно специализировать шаблон члена класса, если его встроенные шаблоны классов также явно не специализируются как.
Я думаю, что ваш лучший вариант - добавить дополнительный параметр в MyClass
, а затем частично специализировать его.
Ответ 2
Это грустно, но верно: вы не можете явно специализировать шаблон класса, если его встроенные шаблоны классов также явно специализированы. Для получения дополнительной информации вы можете прочитать
Ниже я специализировался на MyClass, и все было сделано.
#include <iostream>
using namespace std;
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
template<> template<> int MyClass<char, int>::DoSomething<0>()
{
cout << "This is ZERO!!!" << endl;
cout << "sizeof(T1) = " << sizeof(char) << endl;
cout << "sizeof(T2) = " << sizeof(int) << endl;
return 0;
}
int main() {
MyClass<char, int> m;
m.DoSomething<2>();
m.DoSomething<0>();
return 0;
}
Вывод:
This is the common method
sizeof(T1) = 1
sizeof(T2) = 4
This is ZERO!!!
sizeof(T1) = 1
sizeof(T2) = 4
EUREKA! Это хорошо работает на MSVCPP 10.
#include <iostream>
using namespace std;
template<typename T1, typename T2> class MyClass
{
public:
template<int num> static int DoSomething();
template<> static int DoSomething<0>() {
cout << "This is ZERO!!!" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return 0;
}
};
template<typename T1, typename T2> template<int num> int MyClass<T1, T2>::DoSomething()
{
cout << "This is the common method" << endl;
cout << "sizeof(T1) = " << sizeof(T1) << endl;
cout << "sizeof(T2) = " << sizeof(T2) << endl;
return num;
}
int main() {
MyClass<char, int> m;
m.DoSomething<2>();
m.DoSomething<0>();
return 0;
}
Вывод:
This is the common method
sizeof(T1) = 1
sizeof(T2) = 4
This is ZERO!!!
sizeof(T1) = 1
sizeof(T2) = 4
BTW, не return num;
из специализации. Он никогда не знает, что такое num
.