#include <vector>
using namespace std;
vector<int> f()
{
return{};
}
// Update: Below is not compilable
void g(vector<int>)
{}
// Update: Below is the my initial intent.
/*
void g(const vector<int>&)
{}
*/
void g(vector<int>&&)
{}
int main()
{
auto v1 = f();
auto&& v2 = f();
g(forward<vector<int>>(v1));
g(forward<vector<int>>(v2));
}
Does C++11 guarantee g(forward<vector<int>>(v1))
will call f(vector<int>)
or f(const vector<int>&)
and g(forward<vector<int>>(v2))
will call f(vector<int>&&)
?
The difference is that v1
is a vector while v2
is an rvalue reference to a vector.
Overloading g
the way you have done is a very bad idea. If the argument is a cv-unqualified rvalue, then the call will be ambiguous since both g
's can accept the rvalue with the identity conversion sequence. It is, however, acceptable to have one overload take T&
and the other take T&&
.
If you want to forward the value category of f()
, don't copy/move it as you have done into v1
. That destroys the value category information. v1
will always be an lvalue.
Besides, you are not using std::forward
properly. Both v1
and v2
will be cast to rvalue reference, and would behave the same way under overload resolution in that case.
Here is what the proper usage of std::forward
looks like:
void g(vector<int>&);
void g(vector<int>&&);
int main() {
auto&& v1 = function_returning_lvalue_vector();
auto&& v2 = function_returning_rvalue_vector();
g(forward<decltype(v1)>(v1)); // calls lvalue overload
g(forward<decltype(v2)>(v2)); // calls rvalue overload
}