Определение функции-члена явно специализированного класса вне определения класса
Я вижу ошибку, связанную с шаблонами (компилятор Visual Studio 2012), которые я не понимаю. Здесь код, сведенный к основному:
// Templated class - generic
template <typename T>
class Test
{
public:
void WorksFine() {} // Comiples and works as expected at runtime
void Problem();
};
// Templated class - expicit specialization for T = int.
template <>
class Test<int>
{
public:
void WorksFine() {} // Comiples and works as expected at runtime
void Problem();
};
// The definition below compiles and works fine at runtime.
template<typename T> void Test<T>::Problem() {}
// The definition below gives error C2910.
template<> void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}
Для метода WorksFine определение функции внутри явно специализированное определение класса, и все в порядке. Но для метода "Проблема", когда я определяю метод за пределами явно специализированного определения класса, я получаю ошибку C2910
Почему это? Ошибка C2910 указывает, что проблема в том, что Test:: Problem() уже определен. Но внутри класса определено not... определение функции не является объявлением.
Кажется довольно хромым, что можно что-то делать или нет, в зависимости от того, где вы решите поставить определение функции, которое я всегда был скорее решением стиля/синтаксиса, а не решением функциональности/семантики. Я что-то пропустил?
Ответы
Ответ 1
Вам не нужен template<>
. Просто напишите:
void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}
Синтаксис template<>
для специализации участника требуется там, где явно создается экземпляр элемента самостоятельно; он опущен при определении члена уже существующей специализации.
template<typename T> struct X { static int i; };
template<> int X<int>::i = 0; // member instantiation, uses template<>
template<typename T> struct Y { static int i; };
template<> struct Y<int> { static int i; } // template specialization
int Y<int>::i = 0; // no template<>
Ответ 2
Вам больше не нужно template
в явном определении функции: void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}
В этом случае g++ дает немного лучшее сообщение об ошибке error: template-id 'Problem<>' for 'void Test<int>::Problem()' does not match any template declaration
Ответ 3
Попробуйте следующее:
// The definition below gives error C2910.
void Test<int>::Problem()
{
printf("In Test::Problem(int instantiation)\n");
}
int main()
{
Test<int> hey;
hey.Problem();
return 0;
};