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
后面的用例可能会节省编译时间。
考虑以下示例:
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
后面的用例可能会节省编译时间。