Я пытаюсь переместить определение функции шаблона из файла заголовка.
Я знаю, что для этого я могу явно создать экземпляр этой функции со всеми типами, которые я хочу видеть снаружи (во время связывания). Однако внутри исходного файла (вместе с определением функции) у меня есть использование (неявная реализация) функции со всеми необходимыми типами. Этот код работает и прекрасно связывается с -O0, но не связывается с -O2.
Мне удалось минимизировать проблему:
// a.cpp
#include "b.h"
int main() {
bar<int>();
return 0;
}
// b.h
template <class T> void bar();
// b.cpp
#include "b.h"
template <class T> void bar() {}
void foo() { bar<int>(); }
Если я скомпилирую b.cpp с -O0 и с -O2, я получу другой набор символов, доступный в объектном файле:
> clang++ -c b.cpp -o b.o && nm -A b.o
b.o:0000000000000000 W _Z3barIiEvv
b.o:0000000000000000 T _Z3foov
> clang++ -c b.cpp -O2 -o b.o && nm -A b.o
b.o:0000000000000000 T _Z3foov
То же самое происходит и с gcc .
Похоже, что компиляторы встраивают инстанцированную функцию и удаляют ее, так как они не видят ее другого использования.
Можно ли предотвратить неявное создание экземпляров шаблонных функций без явного их создания?
Заранее спасибо!
UPD : этот ответ на связанный вопрос (как указано @ Jarod42) также отвечает на мой вопрос: согласно стандарту это невозможно сделать без явного конкретизации.