Я не совсем понимаю, как новая функция extern template
предназначена для работы на С++ 11. Я понимаю, что он призван ускорить время компиляции и упростить проблемы с связями с общими библиотеками. Означает ли это, что компилятор даже не анализирует тело функции, заставляя выполнить не-встроенный вызов? Или он просто инструктирует компилятор не генерировать фактический объект метода при выполнении неинтерминированного вызова? Очевидно, что генерация кода link-time не выдерживает.
В качестве конкретного примера, где разница может иметь значение, рассмотрим функцию, которая работает с неполным типом.
//Common header
template<typename T>
void DeleteMe(T* t) {
delete t;
}
struct Incomplete;
extern template void DeleteMe(Incomplete*);
//Implementation file 1
#include common_header
struct Incomplete { };
template void DeleteMe(Incomplete*);
//Implementation file 2
#include common_header
int main() {
Incomplete* p = factory_function_not_shown();
DeleteMe(p);
}
Внутри "файла реализации 2" не указано delete
указатель на Incomplete
. Таким образом, встроенная версия DeleteMe
не удалась. Но если он оставлен в качестве фактического вызова функции, а сама функция была сгенерирована в "файле реализации 1", все будет работать правильно.
Как следствие, являются ли правила одинаковыми для функций-членов шаблонных классов с аналогичным объявлением extern template class
?
В экспериментальных целях MSVC выдает правильный результат для вышеуказанного кода, но если строка extern
удалена, генерируется предупреждение об удалении неполного типа. Тем не менее, это остатки нестандартного расширения, которое они вводили много лет назад, поэтому я не уверен, насколько я могу доверять этому поведению. У меня нет доступа к каким-либо другим средам сборки, чтобы экспериментировать с [save ideone et al., Но в этом случае ограничение ограничивается одной единицей перевода).