Резюме
Этот вопрос касается достижения отдельной компиляции экземпляра экземпляра класса в нескольких разных единицах перевода.Отдельная компиляция и шаблон с явным экземпляром
Вопрос
Для классов нешаблонном можно поместить определения в несколько файлов .cpp и скомпилировать их отдельно. Например:
файл хиджры:
class A {
public:
void func1();
void func2();
void func3() { /* defined in class declaration */}
}
файл A1.cpp:
void A::func1() { /* do smth */ }
файл A2.cpp:
void A::func2() { /* do smth else */ }
Теперь я попытался сделать что-то подобное с классами шаблонов. Поскольку я точно знаю, какие экземпляры мне понадобятся, я явно создаю шаблоны. Я компилирую каждый экземпляр отдельно, потому что функции-члены содержат довольно большие математические выражения, которые могут значительно замедлить компилятор на высоких уровнях оптимизации. Так что я попытался следующее:
файл TA.h:
template <typename T>
class TA {
public:
void func1();
void func2();
void func3() { /* defined in class declaration */}
}
файл TA1.cpp:
template <typename T>
void TA<T>::func1() { /* do smth */ }
template class TA<sometype>;
файл TA2.cpp:
template <typename T>
void TA<T>::func2() { /* do smth else */ }
template class TA<sometype>;
Он работает с clang и GCC в Linux, но не работает с GCC на Mac во время связывания во время ошибки повторяющихся символов (в этом примере из-за func3, который получил экземпляр как в TA1.cpp, так и в TA2.cpp).
Потом я наткнулся на эту фразу в стандарте:
C++ 11.14.7, пункт 5:
Для данного шаблона и заданного набора шаблонов-аргументов,
- явный конкретизации де определению должны появляться не чаще одного раза в программе,
- ...
означает ли это, что отдельный сборник шаблонов классов не представляется возможным (не допускается) даже при использовании экс (очевидно, это невозможно с неявным экземпляром)?
PS Мне все равно, так как у меня есть мой ответ, но тот, кто думает, что здесь отвечает https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file, ошибается.
Очевидно, что это необязательно с неявным экземпляром. –
@LightnessRacesinOrbit, как нужна отдельная компиляция с неявным экземпляром? – Vayun
@Vayun: неявное создание шаблона происходит при использовании. Когда вы используете шаблон в двух или более TU, он был создан компилятором для каждого TU. Компилятор не может знать, что какой-то другой TU уже создавал его. Таким образом, это должно быть законным. –