Почему компоновщик жалуется на несколько определений в этом шаблоне?
Этот маленький фрагмент кода запускает гнев компоновщика, когда он включен, по крайней мере, в два блока перевода (файлы cpp):
# ifndef MAXIMUM_HPP
# define MAXIMUM_HPP
template<typename T>
T maximum(const T & a, const T & b)
{
return a > b ? a : b ;
}
/* dumb specialization */
template<>
int maximum(const int & a, const int & b)
{
return a > b ? a : b ;
}
# endif // MAXIMUM_HPP
Но компилирует и связывает отлично с одной единицей перевода. Если я удалю специализацию, она отлично работает во всех ситуациях. Вот сообщение компоновщика:
g++ -o test.exe Sources\test.o Sources\other_test.o
Sources\other_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)'
Sources\test.o:test.cpp:(.text+0x14): first defined here
Не разрешено ли создание шаблонов несколько раз? Как объяснить эту ошибку и как ее исправить?
Спасибо за любой совет!
Ответы
Ответ 1
Это потому, что полная явная спецификация шаблона должна быть определена только один раз. Хотя компоновщик позволяет определять неявные специализации более одного раза, он не разрешает явные специализации, он просто рассматривает их как нормальную функцию.
Чтобы исправить эту ошибку, поместите все специализации в исходный файл, например:
// header
// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
T maximum(const T & a, const T & b)
{
return a > b ? a : b ;
}
// must be in header file to make sure the compiler doesn't make an implicit
// specialization
template<> int maximum(const int & a, const int & b);
// source
// must be in source file so the linker won't see it twice
template<>
int maximum(const int & a, const int & b)
{
return a > b ? a : b ;
}
Ответ 2
Объявить функции inline
// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
inline T maximum(const T & a, const T & b)
{
return a > b ? a : b ;
}
/* dumb specialization */
template<>
inline int maximum(const int & a, const int & b)
{
return a > b ? a : b ;
}