【问题标题】:C++ template and inlineC++ 模板和内联
【发布时间】:2011-04-11 07:53:13
【问题描述】:

当我编写一个简单的(非模板)类时,如果“就地”提供了函数实现,它会自动被视为inline

class A {
   void InlinedFunction() { int a = 0; }
   // ^^^^ the same as 'inline void InlinedFunction'
}

在谈论基于模板的类时,这条规则怎么样?

template <typename T> class B {
   void DontKnowFunction() { T a = 0; }
   // Will this function be treated as inline when the compiler
   // instantiates the template?
};

另外,inline 规则如何应用于非嵌套模板函数,如

template <typename T> void B::DontKnowFunction() { T a = 0; }

template <typename T> inline void B::DontKnowFunction() { T a = 0; }

第一种情况和第二种情况会发生什么?

谢谢。

【问题讨论】:

  • 请问您为什么想知道这个问题的答案?我已经完成了很多 c++ 编码,而且我还没有遇到过重要的情况。
  • @Benoît 这里也一样,但是最近在编写一些基于模板的代码块时,我了解到我实际上不知道在我所描述的情况下会发生什么。那么为什么不问一个问题呢? :)
  • 不确定您在寻找什么课程问题,但我对答案很感兴趣 :o) 我不相信 DontKnowFunction() 和内联有什么特别之处。如果主体是类声明的一部分,那么它被认为是隐式的,否则使用内联,并且主体在声明之外。
  • @Benoît,知道这会很有趣,特别是如果您害怕对象代码膨胀。

标签: c++ templates inline-method


【解决方案1】:

inline 关键字不是“规则”。它只是对编译器的建议/提示,它的作用完全取决于它和它的实现。考虑到这一点,不可能知道您的示例会发生什么。编译器实际上可能内联所有、部分或不内联。

【讨论】:

  • 我知道 inline 关键字作为推荐,但在第一个示例中(当您在类定义中编写代码时)inline 是“自动添加的”,所以它意味着至少我给编译器这个建议。但我不知道在基于模板的情况下会发生什么。我很确定有一些规则......
  • 是的,但是无论内联是否显式或隐式存在,编译器都可以使用它做什么,因此您无法预先确定编译器的行为。
  • 这实际上不正确@RC。 - “实现不需要在调用点执行[函数体]的这种内联替换;但是,即使省略了这种内联替换,7.1.2 定义的内联函数的其他规则仍应得到遵守。 " [工作草案 7.1.2/2]
  • 当然 - inline 关键字执行 2 个功能:一个是向编译器提示,如果可能,该函数应在调用站点“内联”,编译器可以忽略这一点。 “内联函数的其他规则”允许在每个使用它的翻译单元中定义内联函数。如果您链接 2 个已编译的翻译单元,它们都具有一些非内联函数 foo 的定义,则会产生链接器错误“foo 的多重定义”。
  • @ZacharyKraus 不,它没有。即使编译器不会内联对inline 函数的调用,您也不能调用已声明但未定义的inline 函数。 “内联函数应在使用 odr 的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义。” [N3337 7.1.2/4]
【解决方案2】:

据我所知,模板函数是自动内联的。然而,现实情况是大多数现代编译器经常忽略 inline 限定符。编译器的优化启发式算法在选择内联函数方面很可能比人类程序员做得更好。

【讨论】:

  • 编译器不允许忽略inline 限定符,我不知道有任何现代编译器可以这样做。 inline 对函数的多个定义的语言规则进行了明确定义的特定更改。这不仅仅是一个提示。
  • inline 是一个非常具体和定义的含义。但它与“代码内联”几乎没有关系,大多数现代编译器都忽略了它为“代码内联”提供的hint。它的链接条款和其他东西不容忽视。
  • Charles,编译器可以忽略内联限定符。 parashift.com/c++-faq-lite/inline-functions.html#faq-9.1
  • 根据 [C++ 模板完整指南] (amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/…) 您必须将函数声明为内联
  • @mazhaka 当然:第 6.4 节第 72 页。“这可能会导致函数模板默认为内联的印象。但是,事实并非如此。如果您编写的函数模板应该作为内联处理函数,你应该使用内联说明符(除非函数已经内联,因为它是在类定义中定义的)
【解决方案3】:

因为当你实例化你得到一个类时,这个函数就像一个普通的成员函数。它是在该类中定义的,因此该函数是自动内联的。

但在这里并不重要。无论如何,你可以在一个程序中多次定义函数模板或类模板的成员——你不需要inline 来告诉编译器,就像在非模板的情况下一样。

【讨论】:

  • “在那个类中声明了,”应该改成Defined,不是吗?
  • @JohanLundberg 是的,我相信这就是我想说的。我改了,谢谢。
  • 如果 inline 是一个函数模板的限定符,它不是一个类的成员,会发生什么?内联是否也以这种方式隐含?
猜你喜欢
  • 2011-02-25
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 2013-07-14
  • 2014-06-10
  • 1970-01-01
相关资源
最近更新 更多