inline 关键字对类成员模板函数的影响?

Posted

技术标签:

【中文标题】inline 关键字对类成员模板函数的影响?【英文标题】:Effect of inline keyword on class member template functions? 【发布时间】:2019-11-07 21:30:38 【问题描述】:

我读过关于内联模板函数规范here

除了需要 inline 关键字在标头中进行实例化这是合乎逻辑的之外,我找不到答案是否在标头中将非专用功能模板标记为 inline 有什么不同?无论是成员函数还是普通函数。

请不要解释编译器如何比程序员更清楚,问题是:inline 关键字对于标题中的“解包”模板是否有意义?

非专用模板是否总是内联,因为它们位于标题中?对于下面的示例伪代码,如果我们假设 Foo::bar 方法可以非常长或非常短,省略 inline 关键字或添加 inline 关键字对编译器内联或不内联扩展函数的实际机会有任何影响吗?

这是一个反映我的代码的成员函数模板示例:

class Foo

public:
    template<typename Type>
    static Type bar();
;

非内联定义示例:

template<typename Type>
Type Foo::bar()

    return Type();

内联定义示例:

template<typename Type>
inline Type Foo::bar()

    return Type();

上面的inline 关键字总是没用,还是只有编译器可以内联函数才有意义?模板是否总是内联在标题中?

【问题讨论】:

inline 隐含在第一个块中。我正在尝试在标准中找到对它的引用。 我期待这样的确认,这将回答一切。 我没找到。也许对标准有更深入了解的人可以。 【参考方案1】:

inline关键字用来绕过One Definition Rule,不是用来表示函数调用的inline substitution。请注意,编译器仍然需要函数定义来执行内联替换,因此如果函数的定义位于包含在不同文件中的头文件中,则必须提供 inline

专用函数模板与普通函数一样,因为所有模板参数都已固定(即,函数模板不能部分专用)。因此,如果(完全)专用的函数模板位于头文件中,则应将其设为 inline 以处理单一定义规则,就像处理普通函数一样。

【讨论】:

谢谢,我只对inline substitution 案例感兴趣,我的示例代码与该案例的非专用模板函数上的inline 关键字有什么区别吗?例如,我想提示编译器在调用站点中内联“扩展”模板函数。 我认为您将不得不查看特定于编译的文档。无论如何,如果您想要内联替换函数,请记住编译器必须具有该函数的定义,以便在调用此函数时立即内联。否则,编译器如何执行内联替换? 好吧,如果模板函数是在头文件中定义的,那么编译器确实可以看到定义,对吧?我并不是要在源文件中定义模板并将inline 放在标题中。或不包含调用和扩展函数的标头。 @metablaster 是的,模板函数默认为inlineinline 也被自动添加到类定义中定义的函数中。因此,它也适用于类的成员函数。【参考方案2】:

我想我发现了一些关于这个的东西,看起来 inline 确实 对标头 IE 中的模板定义产生了影响。如果省略inline,则该函数不是内联函数!

Reference link

引用:

例如,考虑头文件 Foo.h,其中包含 以下模板类。 请注意,方法 Foo::f() 是内联的,并且 方法 Foo::g() 和 Foo::h() 不是。

// File "Foo.h"
template<typename T>
class Foo 
public:
  void f();
  void g();
  void h();
;
template<typename T>
inline
void Foo<T>::f()

  // ...

看起来我们可以安全地得出结论,模板不是隐式内联的,但 sample 暗示其他 2 个方法是在 cpp 文件中定义的,所以所有的结论都是错误的。仍在寻找一些标准的确认。

【讨论】:

【参考方案3】:

它会影响显式实例化声明的行为(以一种旨在鼓励内联函数模板的实际内联的方式)。在 C++20 的模块中,它还会影响使用 internal-linkage例如static)实体来自这样的模板的能力——再一次,以一种鼓励内联进口商的方式。在后一种情况下,类中的定义不再意味着inline

【讨论】:

以上是关于inline 关键字对类成员模板函数的影响?的主要内容,如果未能解决你的问题,请参考以下文章

inline类型的成员函数

通过索引对类模板成员的编译时访问

将 inline 关键字与模板一起使用是不是有意义?

函数模板

将成员函数传递给模板函数时出现语法错误

面向对象