Предположим, что файл заголовка определяет шаблон функции. Теперь предположим, что два файла реализации #include
этот заголовок, и каждый из них имеет вызов шаблона функции. В обоих файлах реализации шаблон функции создается с тем же типом.
// header.hh
template <typename T>
void f(const T& o)
{
// ...
}
// impl1.cc
#include "header.hh"
void fimpl1()
{
f(42);
}
// impl2.cc
#include "header.hh"
void fimpl2()
{
f(24);
}
Можно ожидать, что компоновщик будет жаловаться на несколько определений f()
. В частности, если f()
не будет шаблоном, это действительно так.
- Почему линкер не жалуется на несколько определений
f()
? - В стандарте указано, что компоновщик должен обработать эту ситуацию изящно? Другими словами, могу ли я всегда рассчитывать на программы, подобные описанным выше, для компиляции и ссылки?
- Если компоновщик может быть достаточно умным, чтобы устранить неоднозначность набора экземпляров шаблонов функций, почему он не может сделать то же самое для обычных функций, учитывая, что они идентичны, как в случае с экземплярами шаблонов функций?