предположите, что у меня есть файл alpha.h:
class Alpha {
public:
template<typename T> void foo();
};
template<> void Alpha::foo<int>() {}
template<> void Alpha::foo<float>() {}
Если я включаю alpha.h больше чем в один cpp файл и компиляцию с GCC 4.4, это жалуется, что существуют повторные определения foo<int>
и foo<float>
через несколько объектных файлов. Имеет смысл мне, таким образом, я изменяю последние две строки на:
template<> extern void Alpha::foo<int>() {}
template<> extern void Alpha::foo<float>() {}
Но затем GCC заявляет:
явная шаблонная специализация не может иметь класса памяти
хорошо... поэтому, как я, как предполагается, делаю это правильно? Я волнуюсь, что C++ не позволяет то, что я пытаюсь сделать во-первых, в этом случае существует ли хорошая идиома, которая выполнит то же самое?
использовать ключевое слово inline
template<> inline void Alpha::foo<int>() {}
альтернативно, предоставить реализацию в отдельном cpp-файле
Вы можете пересылать объявления, а также использовать опцию inline:
// .h
template<> void Alpha::foo<int>();
//.cpp
template<> void Alpha::foo<int>() {}
С точки зрения ODR, полностью (явно) специализированный шаблон больше не является шаблоном, поэтому он подчиняется тем же принципам ODR, что и объект того же типа, не являющийся шаблоном. (Думаю, есть некоторые исключения из этого правила, но для наших целей этого вполне достаточно).
В вашем случае для целей ODR полностью специализированный шаблон функции является обычной функцией. Итак, как обычная функция, она должна быть объявлена в файле заголовка и определена в одном и только одном файле реализации.