模板类的方法是不是隐含内联链接?

Posted

技术标签:

【中文标题】模板类的方法是不是隐含内联链接?【英文标题】: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 并且函数在翻译单元中离线生成)。尝试在两个翻译单元中获取内联函数的地址(这将强制进行行外定义,以防您的编译器默认情况下不这样做),然后检查二进制文件中导出了哪些符号,您将看到那个内联函数。 【参考方案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。

以上是关于模板类的方法是不是隐含内联链接?的主要内容,如果未能解决你的问题,请参考以下文章

抽象类的模板方法设计模式

带有模板类的 Windows DLL 链接器错误

DLL-导出模板基类的静态成员

如果给定模板参数,是不是有可以将模板类转换为实际类的 C++ 工具? [关闭]

模板方法设计模式

模板方法(TemplateMethod)