【问题标题】:Is "inline" needed with member function templates成员函数模板是否需要“内联”
【发布时间】:2012-09-23 08:10:45
【问题描述】:

如果我在非模板类中有一个成员函数模板并想在类外定义它 - 我必须使用“内联”吗?

例子:

class A
{
    template <class D>
    void someMethod(D param);
}

template <class D>
/* inline needed here? */ void A::someMethod(D param)
{
}

标准的第 3.2.5 节说函数模板不属于单一定义规则。成员函数模板就是这方面的函数模板吗?

编辑:链接器不会抱怨没有内联 - 但仍然 - 它是有效的 C++03 吗?

编辑:

到目前为止我所学到的:gcc(假设还有其他编译器)将隐式模板实例导出为弱符号,这意味着如果它们在多个翻译单元中实例化,则在链接时不会发生冲突.由于弱符号不是标准的一部分 - 标准是否以某种方式隐含地要求模板实例以这种方式运行,我是否可以期望与其他符合标准的编译器/链接器组合具有相同的行为?

由于 inline 基本上被忽略以进行优化,但允许在不同的翻译单元中定义多个函数,这隐含地转换为将这些函数导出为 weak symbols。这是否意味着将模板声明为 inline 是多余的?

【问题讨论】:

  • 是的,编译器不会抱怨。然而,并非所有满足编译器的东西都是有效的 C++ ;) 我们只是在这里进行了讨论,没有人很确定。
  • 编译器不会抱怨,因为它一次只能看到一个翻译单元,并且当在两个翻译单元中定义某些内容时会发生 ODR 冲突。
  • inline 有什么语法意义吗?我一直以为这只是对编译器的优化建议。
  • @Philipp - 内联有语义;它告诉编译器在不同的翻译单元中对同一个内联函数的多个定义并不违反单一定义规则。它还强加了自己的规则,即所有定义必须相同。
  • 只需查看您的 C++ 书籍中的 ODR(一个定义规则),一切都会变得更加清晰。

标签: c++ templates


【解决方案1】:

无论成员函数模板是否是函数模板,它们肯定不是对象或非内联函数,因此不适用单一定义规则。

但它们实际上是函数模板,并且对于不特定于非成员函数模板的标准的其他应用程序来说确实如此。

【讨论】:

    【解决方案2】:

    inline 作为关键字向编译器建议标记为这样的函数是具有相同名称的优化的良好候选者,并且作为实现此类优化的帮助,它要求定义函数 - - 以相同的方式 -- 在每个使用它的 CU 中(如果编译器看到代码,它会更容易进行优化,即使链接器能够进行相同的优化,它20 年前远不常见)。

    您可能希望为函数模板提供此提示,从而将函数模板定义标记为内联。如果您不想给出该提示,则不需要 inline。

    (有一段时间只考虑标记为 inline 的函数进行优化,但该关键字尚未达到register 的命运,即通常被编译器忽略,除了它的正式含义是防止取变量的地址)。

    【讨论】:

    • 嗯...inline 更多的是避免 ODR 违规,而不是提示编译器。有一段时间,编译器认为这是一个很好的提示,然后他们认为人们并不真正知道,编译器开始忽略它作为性能提示。然后编译器产生了他们自己的非标准性能提示,这些提示将强制内联。然后他们决定人们并不真正知道,所以即使是那些非标准的形式也经常被编译器忽略......
    • @DavidRodríguez-dribeas,我的理解是它确实被认为是一种暗示。不是强制要求,但也没有完全忽略(如register 是),只是在或多或少复杂的函数中评估应用优化的兴趣的一个附加参数,并且可能是一个随时间降低重要性的参数(过程驱动不仅通过内联算法的改进,而且(ab?)使用内联来实现该目标的“仅标题”库的数量,降低了其作为优化驱动程序的价值)。
    • @AProgrammer 您的理解部分错误。是的,就实际内联而言,实现可以随意忽略它。但此外,有效地声明内联函数要求实现将所有定义(必须“完全相同”——草案 n4659, 10.1.6/6)“折叠”为一个。这可以防止在链接阶段出现重复的符号错误,否则会发生这种错误。从用例中可以清楚地看出,在标头中包含内联定义,该标头可能包含在许多地方,从而减轻了链接器的内联职责。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 2016-10-05
    • 1970-01-01
    • 2013-12-20
    • 2014-08-10
    • 1970-01-01
    相关资源
    最近更新 更多