【问题标题】:Are methods of templated classes implied inline linkage?模板类的方法是否隐含内联链接?
【发布时间】:2012-07-17 17:08:44
【问题描述】:

模板类的方法是隐含的inline 链接(不是在谈论内联优化),还是只是模板化的方法?

// A.h

template<typename T>
class A
{
public:
    void func1();                       //  #1
    virtual void func2();               //  #2
    template<typename T2> void func3(); //  #3
};

template<typename T>
void A<T>::func1(){}    //  #1

template<typename T>
void A<T>::func2(){}    //  #2

template<typename T>
template<typename T2>
void A<T>::func3<T2>(){}    //  #3

以上情况都是inline【联动】吗? (我应该为其中任何一个明确写inline)吗?

【问题讨论】:

  • 如果它们都在头文件中,你应该为它们都写inline
  • @user315052 为什么?我认为你不应该标记它们inline,并让编译器(比你聪明)来决定是否内联。
  • @JonathonReinhart 这涉及内联链接,而不是复制粘贴类型的内联
  • @ildjarn:我很确定模板函数和模板类成员函数在这方面是特殊的,我想出的快速测试似乎表明了这一点。我还没有标准的报价。
  • @Dave:那不是linkage,只是inline与否。链接影响符号是否在翻译单元中导出,并导出inline 函数(可能是,如果不是static 并且函数在翻译单元中离线生成)。尝试在两个翻译单元中获取内联函数的地址(这将强制进行行外定义,以防您的编译器默认情况下不这样做),然后检查二进制文件中导出了哪些符号,您将看到那个内联函数。

标签: c++ templates inline linkage


【解决方案1】:

如果模板类的模板函数和成员函数被隐式实例化,则它们是隐式内联1,但要注意模板特化不是。

template <typename T>
struct test {
    void f();
}
template <typename T>
void test<T>::f() {}           // inline

template <>
void test<int>::f() {}           // not inline

由于缺乏更好的报价:

必须在隐式实例化 (14.7.1) 的每个翻译单元中定义非导出模板,除非在某个翻译单元中显式实例化相应的特化 (14.7.2);无需诊断


1 仅在允许对它们进行多个定义的意义上,但不允许用于优化目的。您可以手动将它们标记为inline 作为优化器的提示。

请参阅 [basic.def.odr]/13.4 - 模板本身不受 ODR 影响,而不是因为它们隐含为 inline

【讨论】:

  • 是的,但是“模板类的方法是内联的,还是只是模板化的方法?”不过,我对专业不了解,很高兴知道!
  • @DavidRodríguez-dribeas:引用并没有说模板隐式内联如果它们被隐式实例化
  • @Nawaz:inline 表示如果在程序内的多个翻译单元中定义它,则不违反 ODR 规则。引用声明您需要在程序中提供多个翻译单元(与odr-use一样多)的定义。在程序中提供多个定义的要求似乎很好地暗示了这样做并不违反 ODR,这实际上与 inline
  • @Nawaz:你也可以通过相反的假设来证明这一点。假设它们不是inline,则意味着多个定义将违反 ODR,而这反过来又意味着上面的引用迫使您违反 ODR,因为它需要多个定义。假设标准不强制违反标准,前提一定是错误的。
  • @Nawaz:ODR 规则规定,对于每个非内联函数,整个程序中必须有一个定义,而不是每个 TU。 inline 关键字提示您要执行替换的编译器,但重要的部分是函数的定义必须存在于使用它的所有 TU中在不违反 ODR 的情况下。虽然编译器可以忽略 hint 并产生一个外联定义(大多数编译器即使内联也会产生一个外联定义),但这并不违反 ODR。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多