C++:对模板使用 "extern" 关键字是否有意义?

C++: Is there any sense using the "extern" keyword for templates?

考虑以下示例:

fnc.h:

#include <iostream>

template <class T> //common template definition
void fnc()
{
    std::cout << "common";
}

fnc.cpp:

#include "fnc.h"

template<> //specialization for "int"
void fnc<int>()
{
    std::cout << "int";
}

main.cpp

#include "fnc.h"

extern template void fnc<int>(); // compiler will not generate fnc<int> and linker will be used to find "fnc<int>" in other object files

int main()
{
    fnc<double>(); //using instantiation from common template
    fnc<int>(); using specialization from "fnc.cpp"
}

然后我将 extern template void fnc<int>(); 替换为 template<> void fnc<int>(); 并假设行为相同。将 extern 关键字与模板一起使用是否有任何实际意义,还是仅出于可读性而引入?

它不适合专业化。从技术上讲,您所做的是 ill-formed,不需要诊断。您有一个显式实例化声明,但没有匹配的定义。显式特化不计入与您提供的声明的匹配(即使某些编译器以隐藏事实的方式实现它)。

此构造用于延迟实例化,使编译器不会尝试在当前翻译单元中实例化模板。所以你可以用它来完全隐藏模板并只暴露有限的类型集:

Header:

template <class T>
void fnc();

extern template void fnc<int>(); // The instantiation is elsewhere.

来源:

template <class T> //common template definition
void fnc()
{
    std::cout << "common";
}

template void fnc<int>(); // explicit instantiation

或者为了防止在每个 TU 中实例化经常使用的专业:

普通header:

#include <vector>
extern template std::vector<unsigned char>; // look for member definitions elsewhere.

一个源文件:

template std::vector<unsigned char>; // The member functions are defined in this TU

后面的用例可能会节省编译时间。