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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10535667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:11:22  来源:igfitidea点击:

Does it make any sense to use inline keyword with templates?

c++templatesinline

提问by doc

Since templates are defined within headers and compiler is able to determine if inlining a function is advantageous, does it make any sense? I've heard that modern compilers know better when to inline a function and are ignoring inlinehint.

由于模板是在头文件中定义的,并且编译器能够确定内联函数是否有利,这是否有意义?我听说现代编译器更了解何时内联函数并且忽略inline提示。



edit: I would like to accept both answers, but this is not possible. To close the issue I am accepting phresnel's answer, because it received most votes and he is formally right, but as I mentioned in comments I consider Puppy's and Component 10's answers as correct ones too, from different point of view.

编辑:我想接受这两个答案,但这是不可能的。为了结束这个问题,我接受了phresnel的答案,因为它获得了最多的选票,而且他在形式上是正确的,但正如我在评论中提到的,我认为PuppyComponent 10的答案也是正确的,从不同的角度来看.

The problem is in C++ semantics, which is not strict in case of inlinekeyword and inlining. phresnelsays "write inline if you mean it", but what is actually meant by inlineis not clear as it evolved from its original meaning to a directive that "stops compilers bitching about ODR violations" as Puppysays.

问题在于 C++ 语义,它在inline关键字和内联的情况下并不严格。phresnel说“如果你是认真的,就写内联”,但实际上是什么意思inline并不清楚,因为它从其原始含义演变为“阻止编译器对 ODR 违规行为发牢骚”的指令,正如Puppy所说。

采纳答案by Sebastian Mach

It is not irrelevant. And no, not every function template is inlineby default. The standard is even explicit about it in Explicit specialization([temp.expl.spec])

这并非无关紧要。不,并不是每个函数模板都是inline默认的。该标准甚至在显式专业化([temp.expl.spec]) 中对此进行了明确说明

Have the following:

具备以下条件:

a.cc

a.cc

#include "tpl.h"

b.cc

抄送

#include "tpl.h"

tpl.h(taken from Explicit Specialization):

tpl.h(取自显式专业化):

#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}

template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif

Compile this, et voila:

编译这个,等等:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

Not stating inlinewhen doing explicit instantiation may also lead to issues.

inline在进行显式实例化时不说明也可能导致问题。

So in summary: For non fully specialized function templates, i.e. ones that carry at least one unknown type, you can omit inline, and not receive errors, but still they are not inline. For full specializations, i.e. ones that use only known types, you cannot omit it.

所以总而言之:对于非完全专业化的函数模板,即携带至少一种未知类型的函数模板,您可以省略inline,并且不会收到错误,但它们仍然不是inline。对于完全专业化,即仅使用已知类型的专业化,您不能省略它。

Proposed rule of thumb: Write inlineif you mean it and just be consistent. It makes you think less about whether to or not to just because you can. (This rule of thumb is conforming to Vandevoorde's/Josuttis's C++ Template: The Complete Guide).

建议的经验法则inline如果你是认真的,就写下来,并且保持一致。它让你更少考虑是否去或不去,因为你可以。(此经验法则符合Vandevoorde/Josuttis 的C++ 模板:完整指南)。

回答by Puppy

It's irrelevant. All templates are already inline- not to mention that as of 2012, the only use of the inlinekeyword is to stop compilers bitching about ODR violations. You are absolutely correct- your current-generation compiler will know what to inline on it's own and can probably do so even between translation units.

这无关紧要。所有模板都已经inline- 更不用说截至 2012 年,该inline关键字的唯一用途是阻止编译器抱怨 ODR 违规。您是绝对正确的 - 您当前的编译器将知道自己内联什么,甚至可能在翻译单元之间这样做。

回答by Component 10

As you suggested, inlineis a hint to the compiler and nothing more. It can choose to ignore it or, indeed, to inline functions not marked inline.

正如您所建议的,inline是对编译器的提示,仅此而已。它可以选择忽略它,或者实际上是内联未标记为内联的函数。

Using inlinewith templates used to be a (poor) way of getting round the issue that each compilation unit would create a separate object for the same templated class which would then cause duplication issues at link time. By using inline(I think) the name mangling works out different which gets round the name clash at link time but at the expense of vastly bloated code.  

使用inline与曾经是变圆了这个问题,每个编译单元将创建一个单独的对象为同一模板类的(差)的方式模板,然后会导致在链接时重复的问题。通过使用inline(我认为)名称修改可以解决链接时的名称冲突问题,但代价是大大膨胀的代码。  

Marshall Cline explains it herebetter than I can.

Marshall Cline在这里解释得比我好。