Правило единого определения гласит, что программа должна содержать одно определение каждой не встроенной функции. Для членов шаблонных классов это не совсем понятно для меня:
///////////
// 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)
Возможно, это неправильное представление, но разве функции-члены шаблонных классов не всегда «встроены»? Какое правило здесь?
Функция-член явная специализация шаблона класса так же, как функция-член класса не шаблон. Ведь явная специализация является конкретный класс, который не зависит от какого-либо параметра шаблона.
Если вы поместите его определение в заголовочный файл, который включен несколькими модулями перевода, компилятор создаст объектный код для этой функции при обработке каждого из этих модулей перевода.
В конце концов, компоновщик будет жаловаться на несколько определенных символов. inline
Ключевое слово предотвращает такое поведение, так же как и для обычных не шаблонных функций или обычных функций-членов не шаблонных классов.
Вы можете переместить определение явной специализации
void Foo<int>::foo() {}
в файл .cpp.
Оставьте объявление в .h:
template<>
void Foo<int>::foo();