【问题标题】:C++: Is there any sense using the "extern" keyword for templates?C++:对模板使用“extern”关键字有什么意义吗?
【发布时间】:2019-09-23 09:01:25
【问题描述】:

考虑以下示例:

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

【问题讨论】:

标签: c++ templates linker instantiation extern


【解决方案1】:

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

此构造用于延迟实例化,以使编译器不会尝试在当前翻译单元中实例化模板。因此,您可以使用它来完全隐藏模板并仅针对有限的一组类型公开:

标题:

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 中实例化一个常用的特化:

通用标题:

#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

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

【讨论】:

  • 它不能也用于“隐藏”(例如,防止不断重新编译)模板最频繁的实例化以减少编译/链接时间吗?
  • @Max - 也是。我会改写
猜你喜欢
  • 2011-02-14
  • 1970-01-01
  • 2017-01-08
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
相关资源
最近更新 更多