从函数调用传递参数或从变量传递参数之间的 C++ 区别
C++ difference between passing argument from a function call or passing argument from variable
这有什么区别:
function1(function2());
还有这个:
var1 = function2();
function1(var1);
就效率或其他方面而言,最佳选择是什么?
在 C++11 之前没有太大区别。由于引入了移动语义,因此差异可能很大。例如,当一个函数需要复制其参数时,它可以有两个重载:一个实际复制一个副本,另一个可以在参数是临时参数时移动:
#include <iostream>
struct bar {};
bar b() { return {};}
struct foo {
bar b;
void set(const bar& in) {
std::cout << "copy \n";
b = in;
}
void set(bar&& in){
std::cout << "no need to copy, can move\n";
b = std::move(in);
}
};
int main() {
foo f;
bar b1;
f.set(b1);
f.set(b());
}
bar
在这个例子中只是一个轻量级的 class,但是当移动成本低但复制成本高时,f.set(b1)
的效率低于 f.set(b())
。调用者可以 f.set(std::move(b1))
,但调用 f.set(b())
比让对象闲逛更清楚。
然而,在 C++11 之前,您实际上应该问的问题是:为调用 function2
的结果命名是否有意义?您只需要结果来调用 function1
还是在其他地方也需要它?并且无论您是在编写古老的 C++ 还是涉及移动语义,都可以独立地回答这个问题。简而言之:编写代码要清晰易读。对效率的关注是在稍后阶段,当您拥有可以测量和分析的正确且有效的代码时。
这有什么区别:
function1(function2());
还有这个:
var1 = function2();
function1(var1);
就效率或其他方面而言,最佳选择是什么?
在 C++11 之前没有太大区别。由于引入了移动语义,因此差异可能很大。例如,当一个函数需要复制其参数时,它可以有两个重载:一个实际复制一个副本,另一个可以在参数是临时参数时移动:
#include <iostream>
struct bar {};
bar b() { return {};}
struct foo {
bar b;
void set(const bar& in) {
std::cout << "copy \n";
b = in;
}
void set(bar&& in){
std::cout << "no need to copy, can move\n";
b = std::move(in);
}
};
int main() {
foo f;
bar b1;
f.set(b1);
f.set(b());
}
bar
在这个例子中只是一个轻量级的 class,但是当移动成本低但复制成本高时,f.set(b1)
的效率低于 f.set(b())
。调用者可以 f.set(std::move(b1))
,但调用 f.set(b())
比让对象闲逛更清楚。
然而,在 C++11 之前,您实际上应该问的问题是:为调用 function2
的结果命名是否有意义?您只需要结果来调用 function1
还是在其他地方也需要它?并且无论您是在编写古老的 C++ 还是涉及移动语义,都可以独立地回答这个问题。简而言之:编写代码要清晰易读。对效率的关注是在稍后阶段,当您拥有可以测量和分析的正确且有效的代码时。