явная специализация метода класса — символ уже определен

Правило единого определения гласит, что программа должна содержать одно определение каждой не встроенной функции. Для членов шаблонных классов это не совсем понятно для меня:

 ///////////
// Tfoo.h
template<typename T> class A {
void foo(){}
};

///////////
// intfoo.h
#include <Tfoo.h>
template<> class Foo<int> {
void foo(); // declaration only
};
/*inline*/ void Foo<int>::foo(){} // definition

///////////
// X.cpp
#include <intfoo.h>

///////////
// Y.cpp
#include <intfoo.h>

В этом случае и clientX.obj, и clientY.obj имеют определение Foo<int>::foo, Компоновщик жалуется, что этот символ определен более одного раза:

Y.obj : error LNK2005: "private: void __thiscall Foo<int>::foo(void)"(?foo@?$Foo@H@@AAEXXZ) already defined in X.obj

Когда я готовлюсь inline к определению Foo<int>::foo(), все идет хорошо, и компоновщик счастлив. Также, когда я определяю их метод в отдельном модуле компиляции (например, intfoo.cpp).

(Примечание: это решение было предложено в https://stackoverflow.com/a/1481796/6610)

Возможно, это неправильное представление, но разве функции-члены шаблонных классов не всегда «встроены»? Какое правило здесь?

5

Решение

Функция-член явная специализация шаблона класса так же, как функция-член класса не шаблон. Ведь явная специализация является конкретный класс, который не зависит от какого-либо параметра шаблона.

Если вы поместите его определение в заголовочный файл, который включен несколькими модулями перевода, компилятор создаст объектный код для этой функции при обработке каждого из этих модулей перевода.

В конце концов, компоновщик будет жаловаться на несколько определенных символов. inline Ключевое слово предотвращает такое поведение, так же как и для обычных не шаблонных функций или обычных функций-членов не шаблонных классов.

8

Другие решения

Вы можете переместить определение явной специализации

void Foo<int>::foo() {}

в файл .cpp.
Оставьте объявление в .h:

template<>
void Foo<int>::foo();
1

По вопросам рекламы [email protected]