#include <vector>
std::vector<int> f()
{
return std::vector<int>(1024);
}
void use_1(std::vector<int> const&)
{}
void use_2(std::vector<int> const&)
{}
int main()
{
{
auto const& v = f(); // style 1
use_1(v);
use_2(v);
}
{
auto&& v = f(); // style 2
use_1(v);
use_2(v);
}
{
auto v = f(); // style 3
use_1(v);
use_2(v);
}
}
Which is better? style 1, style 2, or style 3?
In my opinion, if the return type doesn't implement move-semantics, then style 1 and style 2 are more efficient than style 3.
By-value won't be wrong and it's no-less efficient. The life-time is clear, it won't ever dangle. Reference versions are error-prone. Take this example:
#include <utility>
struct Bar {};
template <class T>
auto&& foo(T&& t) {
return std::forward<T>(t);
}
int main() {
auto&& bar = foo(Bar{});
// bar dangles
}
You may think "this will never happen" but as the code base gets more complicated it does happen. Keep it simple.