15

运算符和其他在 C++ 中进行内联的方法之间有什么区别吗?我已经搜索过了,但正如我所见,这不是一个常见的问题。有没有人有充分的理由使用或避免使用它?注意:显然,我指的是小的内联运算符。

4

3 回答 3

17

虽然这可能因编译器而异,但我希望从编译器的角度来看,运算符只是另一个名称有点不寻常的函数,它允许源代码的语法看起来有点不同。

尽管如此,当编译器的代码生成器部分运行时,我预计重载运算符和另一个函数(执行相同操作)之间的任何差异都会消失。

因此,inline在类定义的主体中声明或定义它将与任何其他函数一样具有(很少,取决于您的观点)运算符重载。我通常希望在这两种情况下这种影响都非常小——至少在启用优化时,大多数编译器几乎都会忽略该inline关键字,并自行决定要扩展哪些内联(以及哪些不扩展)。

请注意,编译器虽然不能忽略inline关键字的一种方式——必须遵守对“单一定义规则”的一些​​特殊修改,无论函数是否实际上是内联扩展的。

于 2013-01-09T00:52:59.900 回答
9

您可以使用inline关键字向编译器建议内联函数。

编译器没有义务服从这个要求。

运算符是相似的——它们可能是内联的,也可能不是内联的。

由于不能强制编译器内联,因此可能没有充分的理由使用或避免使用内联提示。因为这就是它们的全部:提示。

在 Visual C++ 中,您可以使用__forceinline关键字强制内联,结果是更大的代码和潜在的性能损失。在精心设计的系统中,消除选项(通过强制执行)通常会导致性能下降,这是很常见的。即使你使用这个关键字,也不是每个函数都能成功内联。

在这里讨论 GCC 内联。

于 2013-01-09T00:56:33.443 回答
2

正如其他人提到的,编译器是否“内联”一个方法通常不代表您,关于inline关键字的使用和编译器的优化策略。

所以我认为更重要的方面是头文件的可读性,并且operator方法可能会出现为例如算术运算实现的集合,其中可以使用简单的转换来构建它们。因此,如果我必须查看这样的头文件,我希望一起查看逻辑相关的运算符方法签名集,以大致了解什么是适用的或不适用的。

一个非常简单的例子是operator==()and的实现operator!=()

class A
{
public:

    // Equality tests
    //-----------------------------------------------------------------------

    // This may involve some mor complex code that'll look ugly here
    bool operator==(const A& rhs) const;

    // Fine, this is a one liner. Code appears 'inline' (and is likely to be 
    // chosen for inlining by the compiler, no matter if inline keyword or not)
    bool operator!=(const A& rhs) const { return !A::operator==(rhs); }
};
于 2013-01-09T01:27:29.403 回答