在"类定义"中定义的C++成员函数中隐式"内联"

Sam*_*Sam 36 c++ inline class

根据C++规范,以下两个类是否等效定义?

class A
{
   void f()
   {
   }
};

class B
{
   inline void f()
   {
   }
};
Run Code Online (Sandbox Code Playgroud)

即,将"内联"限定符放在类定义中定义的成员函数上是完全冗余的吗?

跟随问题:假设它是多余的,对于代码样式,保留"内联"标记是否明智,以便未来的开发人员意识到该函数应该内联,并且不会删除其他地方的定义并删除内联?

谢谢 :)

cra*_*gmj 90

C++ ISO标准说:

"在类定义中定义的函数是内联函数."

但是,这并不意味着函数必然会被内联:通常现在,编译器似乎会决定内联函数是否会带来任何好处.

  • 这是一个比接受的答案更好的答案 (26认同)
  • 现代 C++ 中的“inline”关键字不再是实际内联,而是暂时解除“单一定义规则”,只要所有定义都相同,以便仅包含头文件的库成为可能。 (4认同)

Ste*_*sop 20

除了"一个定义规则"的目的之外,它们是等同的类定义.因此,该标准不保证您可以使用一个类定义和另一个TU编译一个TU(转换单元),然后将它们链接在一起.我怀疑这在真正的实现上实际上是否会失败,但这就是标准所说的.

inline关键字与内联几乎没有任何关系.它是关于在不同的TU中是否允许多个相同的函数定义.如果有人将函数定义移到别处,那么他们应该决定是否inline按以下方式标记它:

  • 如果它在.cpp该类的文件中,那么inline只有从该TU调用它才有效.然后它是否标记可能没有区别inline,但inline如果您认为编译器会关注您想要的内容,您可以将其标记为编译器提示.

  • 如果它仍然在头文件中,那么它必须被标记inline,否则在链接使用头的不同TU时你会得到多个定义错误.

假设移动函数的人知道这些事情,我认为他们不需要在类定义中提醒.如果他们不了解这些事情,那么他们可能没有业务移动功能,但是让他们使用inline关键字来移动它会更安全.

  • TU应该是"翻译单位"我猜.刚想通了,并在这里评论了其他人的方便. (14认同)
  • [这个答案](http://stackoverflow.com/a/8393102/1600898)引用了C++98标准的说法,*成员函数可以在其类定义中定义(8.4),在这种情况下,它是一个内联成员函数(7.1.2)* 这似乎与答案的第一句相矛盾;根据标准的引用,两个类定义都定义了内联成员函数“f”,这是 ODR 明确允许的。 (2认同)
  • @user4815162342:允许“class A {void f() {}};”或“class A {inline void f() {}};”,但 ODR 禁止您在不同的 TU 中使用它们,然后将这两个 TU 连接在一起。ODR 允许链接内联函数的两个定义(就此而言,一个类的两个定义),前提是它们相同,这意味着它们必须包含相同的标记序列。由于一个定义包含标记“inline”,而另一个定义不包含标记,因此不允许它们在同一程序中同时定义相同的类“A”。 (2认同)
  • 感谢您的澄清,我忘记了“相同的令牌序列”要求。在“出于 ODR 目的”旁边的答案中提及该要求可能是个好主意,因为如果将两个类命名为相同,那么这将是唯一使这两个类“不同”的事情。 (2认同)

Mar*_*ork 9

将"内联"限定符放在类定义中定义的成员函数上是完全冗余的吗?

对于代码样式,保留"内联"标记是否合理,以便未来的开发人员意识到该函数应该内联,并且不会删除其他地方的定义并删除内联?


.内联是针对"一个定义规则"(因此通过扩展链接).如果函数定义在inline需要的位置并且未提供,则为编译时错误.如果不需要那么它只是额外无用的绒毛.

所以,如果你不需要它删除它.如果你需要它把它放在那里(如果你忘了编译器会让你知道).