我应该通过引用或值来引用内联函数的参数吗?

rlb*_*ond 25 c++ inline

其中一个更快吗?

inline int ProcessByValue(int i)
{
    // process i somehow
}

inline int ProcessByReference(const int& i)
{
    // process i somehow
}
Run Code Online (Sandbox Code Playgroud)

我知道整数类型应该按值传递.但是,我担心编译器可能会内联ProcessByValue以包含副本.这有规则吗?

jal*_*alf 26

它没有任何区别.在这两种情况下,代码都将内联到相同的内容.不必要地复制int(以pass-by-value)将被编译器消除,并且不必要地创建对int的引用,并且在访问int时跟随该间接层也将被消除.

你的问题似乎是基于一些错误的假设:

  • 内联关键字实际上会使您的函数内联.(可能,但肯定不能保证)
  • 参考值与值的选择取决于内联函数.(完全相同的性能考虑将适用于非内联函数)
  • 它会产生影响,并且你可以通过这样的微不足道的改变来超越编译器(编译器将在任何一种情况下应用相同的优化)
  • 并且优化实际上会在性能上产生可测量的差异.(即使没有,差异也会小到可以忽略不计.)

我知道整数类型应该按值传递.但是,我担心编译器可能会内联ProcessByValue以包含副本.这有规则吗?

是的,它会创建一个副本.就像通过引用传递将创建引用.然后,至少对于像int这样的简单类型,编译器会再次消除这两种类型.内联函数不允许更改函数的行为.如果你创建函数来获取一个值参数,它的行为就像给它一个值参数一样,无论它是否内联.如果您定义要引用的函数,它将表现为传递引用,无论它是否内联.那么是什么导致了正确的行为.

  • 我刚查过。`f(vector<int> v)` 在 g++ 4.9.2 上使用 `-O2` 或 `-O3` 花费的时间是 `f(const vector<int>& v)` 的两倍。所以,副本没有被优化掉。 (2认同)

Mic*_*urr 19

应根据对函数有意义的内容键入参数.

如果函数采用基本类型,则按值传递是有意义的.我认识的一些人会抱怨如果它被const ref传递(因为它是"不必要的"),但我不认为我会抱怨.如果函数采用用户定义的类型并且不修改参数,那么通过const ref会有意义.

如果它是用户定义的类型并且参数被修改,那么函数的语义将指示它应该如何传递.


Mar*_*som 7

编译器应该能够优化内联函数,以便任一方法都能生成相同的代码.做一个最清楚的.

如果有疑问,请尝试一下.打开编译器的汇编列表输出,看看是否存在差异.