【问题标题】:inline template function?内联模板函数?
【发布时间】:2013-07-14 01:50:08
【问题描述】:

如果inline 模板函数包含在多个cpp 文件中,我是否需要它们?谢谢。

template<bool> inline QString GetText();
template<> inline QString GetText<true>() {return "true";}
template<> inline QString GetText<false>() {return "false";}

【问题讨论】:

标签: c++ template-function


【解决方案1】:

你这样做,因为它们是完整的函数特化,因此像普通函数一样受单一定义规则的约束。

【讨论】:

  • 对于模板而不是完全专业的模板,我可以删除inline关键字。这样对吗?喜欢template&lt;bool&gt; QString GetText();
  • @user1899020:是的,你可以。
【解决方案2】:

是的,你需要 inline 说明符。

ODR(单一定义规则)规定,变量、函数、类、枚举或模板必须只有一个定义。 §3.2/5 (C++11) 中列出了与您的问题相关的例外情况(重点是我的):

类类型(第 9 条)、枚举类型(7.2)、带有外部链接的内联函数(7.1.2)、类模板(第 14 条)、非静态函数模板(14.5)可以有多个定义.6)、类模板的静态数据成员 (14.5.1.3)、类模板的成员函数 (14.5.1.1) 或 未指定某些模板参数的模板特化 (14.7, 14.5.5) 在程序中,前提是每个定义出现在不同的翻译单元中,并且定义满足以下要求。 [...]

其中未列出 所有 参数指定的模板特化(即显式特化),第 14.7.3/12 节说:

函数模板的显式特化只有在使用 inline 说明符声明或定义为已删除时才是内联的,并且与它的函数是否无关 模板是内联的。 [ 例子:

template<class T> void f(T) { /∗ ... ∗/ }
template<class T> inline T g(T) { /∗ ... ∗/ }
template<> inline void f<>(int) { /∗ ... ∗/ }  // OK: inline
template<> int g<>(int) { /∗ ... ∗/ }          // OK: not inline

—结束示例]

【讨论】:

  • 在我的测试中,template&lt;&gt; int g&lt;&gt;(int) { /∗ ... ∗/ } 似乎需要关键字 inline
  • @user1899020 你真的读过答案了吗?如果您将它包含在几个链接在一起的 cpp 文件中,那么是的,您需要内联。这就是示例(来自标准)所说的。
【解决方案3】:

模板方法似乎必须在正在构建的同一文件中定义,您不需要使用'inline'关键字,因为它们是在包含它的每个cpp文件中构建的。

【讨论】:

    【解决方案4】:

    模板声明没有理由 inline 但模板完全专业化没有理由,您不需要为第一行添加 inline 关键字,但第二和第三行需要它。 但是每个使用模板的翻译单元都需要包含模板定义,所以最好的方法是将它包含在头文件中,并包含在其他使用它的cpp中。

    在 3.2/6 的 C++ 标准 n3376 中,如果定义相同,则整个应用程序可以有多个类模板的定义。

    ================

    根据 Jesse Good cmets 更新 answere 基础,(需要内联模板完全专业化)感谢 Jesse Good 指出。

    【讨论】:

    • 您需要inline 关键字。这些是模板专业化,如果包含在多个源文件中会违反 ODR。
    • 参见[temp.expl.spec]/12 “函数模板的显式特化只有在使用 inline 说明符声明或定义为已删除时才是内联的,并且与它的函数模板是否内联无关。”
    • @ZijingWu 你指的是 C++14 的草稿。在当前的 C++11 中,相关部分是 3.2/5。此外,如果您包含完整的引用,您会注意到显式模板特化在该部分中没有作为例外提及(在 C++11 和 C++14 中都没有)。跨度>
    • @jogojapan 我没有注意到 3.2/5 的预期列表中不包含完整的显式模板特殊化。标准是否有任何理由将完全专业化和模板功能不同?我认为应该有一些原因,但我想不通。
    • @ZijingWu 原因是完全(即明确)专用的功能模板不再是模板。它们是函数,其行为方式与函数相同。 (这也反映在您不需要显式特化函数模板的显式实例化这一事实。显式特化意味着对函数的实例化。)
    猜你喜欢
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多