Нормальная функция, не перезаписывающая функцию шаблона

Мне приходится использовать внешнюю библиотеку, но я получаю «множественную ошибку определения» из следующей функции шаблона и ее явной специализации, если она вызывается с помощью std::string.

template <typename T>
void foo(T& value);

template <>
void foo(std::string& value);

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

void foo(std::string& value);

проблема такая же.

Согласно [1] по крайней мере версия без шаблона ("простая старая функция") должна быть предпочтительнее версии с шаблоном.

Кто-нибудь знает, где может быть проблема?

[1] http://www.gotw.ca/publications/mill17.htm


person randooom    schedule 20.09.2010    source источник
comment
Ошибка при компиляции или при линковке? Кроме того, возможно, файл заголовка не очень хорошо защищен макросами, чтобы включать их только один раз.   -  person Diego Sevilla    schedule 20.09.2010
comment
У вас есть только определения функций в вашем заголовочном файле? Вам нужно все тело. См. здесь: parashift.com/c++-faq/templates.html#faq -35,12   -  person Matt K    schedule 20.09.2010
comment
Спасибо, ребята, ответ GMan помог.   -  person randooom    schedule 21.09.2010


Ответы (1)


Вы нарушаете правило одного определения.

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

Однако явная специализация или функция, не являющаяся шаблоном, не является неявно inline, и поскольку вы включаете ее в несколько единиц перевода, вы получаете несколько определений; это нарушает правило. Вы должны пометить его как inline:

template <>
inline void foo(std::string& value);

(Если вы получаете это до времени компоновки, вам нужно включить охрану.)

person GManNickG    schedule 20.09.2010
comment
Просто отметим для дальнейшего использования: $14.7.3/14 — явная специализация шаблона функции является встроенной, только если она явно объявлена ​​таковой и независимо от того, является ли ее шаблон функции. Не могли бы вы сообщить нам ссылку о том, что «функции шаблона неявно встроены»? - person Chubsdad; 21.09.2010
comment
Вы также хотите изменить «шаблонную функцию» на «шаблон функции» и «специализацию на явную специализацию» в своем ответе? +1 уже поставили - person Chubsdad; 21.09.2010
comment
8.1.2 шаблонов C++ (amazon.com/Templates-Complete -Guide-David-Vandevoorde/dp/), упоминает, что шаблоны обычно имеют внешнюю связь. Единственными исключениями являются шаблоны функций области видимости пространства имен со статическим спецификатором: - person Chubsdad; 21.09.2010
comment
@Chubsdad: я говорил слишком свободно. Они не inline, они просто ведут себя похоже (компилятор и/или компоновщик должны быть достаточно умными, чтобы действовать так, как будто он создает его только один раз). - person GManNickG; 21.09.2010