我常常看到变换器函数通过引用获取参数,并且还返回与函数返回值相同的参数。
例如:
std::string& Lowercase(std::string & str){
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}
我理解这是为了方便起见,我的印象是编译器会针对实际未使用返回值的情况进行优化。但是,我不相信编译器可以针对新创建的非基本类型的返回值进行优化。例如:
std::tuple<int,std::string,float> function(int const& num, std::string const& str, float const& f){
return std::tuple<int,std::string,float>(num,str,f);
}
构造函数几乎可以执行任何操作,虽然不使用返回类型,但这并不意味着避免创建类型是安全的。但是,在这种情况下,当不使用函数的返回值时,不创建类型将是有利的。
是否有某种方式通知编译器如果没有使用返回类型,那么避免创建类型是安全的吗?这将是功能特定的,是程序员的决定;不是编译器可以自己解决的问题。
答案 0 :(得分:0)
在function
的情况下,如果函数没有内联might not optimize it since it has non trivial constructor。但是,如果函数是内联的,它可能会优化未使用的返回类,如果它的生命周期不影响任何参数。此外,由于元组是标准类型,我相信大多数编译器将优化返回的变量。
答案 1 :(得分:0)
通常,编译器有两种优化代码的方法:
以下面的代码为例:
struct A {
int v;
};
A foo(int v) {
A a;
a.v = v;
return a;
}
void bar(A& a, int v) {
a.v = v;
}
A f;
f = foo(1);
A b;
bar(b, 1);
在函数foo
中,构造变量a
,修改其成员v
,然后返回。在人工优化版本bar
中,a
会被传入,修改并提供给来电者。
显然,f
和b
是相同的。
如果你对C ++有更多了解,你会知道从foo
返回时,结果a
被复制到外f
,而a
的dtor被调用
将foo
优化成bar
的方式称为RVO
,它忽略了内部a
到外部f
的副本。修改直接转到调用者的变量。
请注意,有些情况下RVO不适用:复制ctor有副作用,多次退货等。
优化返回值的另一种方法是使用C ++ 11中引入的rvalue ctor
。一般来说,就像调用std::swap(vector_lhs, vector_rhs)
交换内部数据指针以避免深层复制一样。
这是一篇关于优化的非常好的文章: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
最后但并非最不重要
在Going Native 2013中,Andrei Alexandrescu介绍了如何编写快速C ++代码。并且通过引用传递比rvalue
更快。 (此外,RVO也有一些限制)因此,如果您关心性能,请使用参考传递。