为什么需要内联模板专业化?

时间:2018-01-23 13:12:54

标签: c++ templates inline template-meta-programming template-specialization

我指的是这个答案:

https://stackoverflow.com/a/4447057/930315

我遇到了与引用问题的OP类似的问题, 有一个功能

template<typename T>
void func(T& val);

及其专业化

template<>
void func<mytype>(mytype& val);

导致重复的符号链接器错误(这些方法在我的标题末尾包含的&.tpp&#39;文件中实现)。 将inline添加到专用函数解决了该问题。为什么呢?

3 个答案:

答案 0 :(得分:10)

好吧,如果你想要这个标准报价,那就结束了[temp.expl.spec]/12

  

函数或变量模板的显式特化是   仅当内联说明符声明或定义为内联时才内联   删除,并独立于其功能或变量   模板是内联的。 [实施例:

Bundle().let{location.extras=it; location.extras}.setBoolean(...)
     

- 结束示例]

这就是你拥有的原因。它是独立的,因为我认为这样做会不必要地限制,正如Yola所证明的那样。

答案 1 :(得分:7)

这将无内联工作:

<强> file1.h

template<typename T> void func(T& val);
template<> void func<mytype>(mytype& val);

<强> file1.cpp

template<> void func<int>(int& ) {}

但是如果您在头文件中定义模板专精,那么您可能会违反ODR

答案 2 :(得分:6)

根据c ++标准中的第3.2:4条

  

每个程序都应包含每个非内联的一个定义   在该程序中使用的函数或变量;没有诊断   需要。定义可以在程序中明确显示,也可以   可以在标准库或用户定义的库中找到,或者(在   适当的)它被隐含地定义(见12.1,12.4和   12.8)。内联函数应在每个使用它的翻译单元中定义。

这解释了为什么在未声明内联专用函数时存在链接时错误。该程序将包含专用函数的多个定义,每个模块包含一个.tpp文件,这会破坏标准的条件。当声明专用函数inline时,它将使该函数满足同一子句的第二部分,即必须使用该函数在每个模块中定义内联函数。

当参数化函数不是专用函数时,它将在第3.2:6节中涵盖:

  

类类型可以有多个定义(第9条),   枚举类型(7.2),带外部链接的内联函数(7.1.2),   类模板(第14章),非静态函数模板(14.5.6),   类模板的静态数据成员(14.5.1.3),成员函数   一个类模板(14.5.1.1),或模板特化,其中一些   程序中未指定模板参数(14.7,14.5.5)   只要每个定义出现在不同的翻译单元

此子句指出,只要在代码中未指定至少一个模板参数,就可以对同一模板函数进行多个定义。这是为了允许决定参数化函数是否应该在仅在本地信息上进行的模块中实例化。