Как обеспечить явную специализацию только для одного метода в шаблонном классе C++?
У меня есть шаблон класса, который выглядит примерно так:
template<class T> class C
{
void A();
void B();
// Other stuff
};
template<class T> void C<T>::A() { /* something */ }
template<class T> void C<T>::B() { /* something */ }
Я хочу предоставить явную специализацию только для A
сохраняя значение по умолчанию для B
и "другие вещи".
Что я пробовал до сих пор
class D { };
template<> void C<D>::A() { /*...*/ } // Gives a link error: multiple definition
Любой другой вариант, который я пробовал, не работает с ошибками разбора
Что я сделал:
Первоначальная проблема заключалась в том, что явная специализация заключалась в заголовочном файле, поэтому он сбрасывался в несколько объектных файлов и портил ссылку (почему компоновщик не замечает, что все экземпляры символа одинаковы, просто заткнись?)
В конечном итоге решение состоит в том, чтобы переместить явную специализацию из файла заголовка в файл кода. Однако, чтобы сделать других пользователей файла заголовка не экземпляром версии по умолчанию, мне нужно было поместить прототип обратно в заголовок. Затем, чтобы GCC фактически генерировал явную специализацию, мне нужно было поместить фиктивную переменную правильного типа в файл кода.
2 ответа
В качестве альтернативы встроенному решению Martin York вы также можете сделать это в своем заголовочном файле:
class D { };
template<> void C<D>::A(); // Don't implement here!
И предоставьте файл.cpp с реализацией:
template<> void C<D>::A() { /* do code here */ }
Таким образом, вы избегаете нескольких определений, предоставляя одно. Также полезно скрывать реализации для определенных типов от файла заголовка шаблона при публикации библиотеки.
Пытаться
template<> inline void c<int>::A() { ... }
// ^^^^^^
Как вы определили это в заголовочном файле. Каждый исходный файл, который его видит, создает его явную версию. Это приводит к вашим ошибкам компоновки. Так что просто объявите его как встроенный.