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

2021-12-13 00:00:00 inline templates c++

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

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 inline hint.

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

edit: I would like to accept both answers, but this is not possible. To close the issue I am accepting Sebastian Mach'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.

问题出在 C++ 语义上,对于 inline 关键字和内联的情况并不严格.Sebastian Mach 说如果你是认真的,就写内联",但是 inline 的实际含义并不清楚,因为它从它的原始含义演变成了一个指令阻止编译器抱怨 ODR 违规"正如小狗所说.

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

推荐答案

这不是无关紧要的.不,并不是每个函数模板默认都是 inline.该标准甚至在显式专业化 ([temp.expl.spec])

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

具备以下条件:

a.cc

#include "tpl.h"

b.cc

#include "tpl.h"

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

编译这个,等等:

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

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

Not stating inline when doing explicit instantiation may also lead to issues.

总结:对于非完全专门化的函数模板,即携带至少一种未知类型的函数模板,您可以省略inline,并且不会收到错误,但仍然它们不是 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.

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

Proposed rule of thumb: Write inline if 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).

相关文章