c++ - Are there any use cases for std::forward with a prvalue? -
the common usage of std::forward to, well, perfect forward forwarding (universal) reference, like
template<typename t> void f(t&& param) { g(std::forward<t>(param)); // perfect forward g } here param lvalue, , std::forward ends casting rvalue or lvalue, depending on argument bounded was.
looking @ definition of std::forward cppreference.com see there rvalue overload
template< class t > t&& forward( typename std::remove_reference<t>::type&& t ); can give me reason why rvalue overload? cannot see use case. if want pass rvalue function, can pass is, no need apply std::forward on it.
this different std::move, see why 1 wants rvalue overload: may deal generic code in don't know you're being passed , want unconditional support move semantics, see e.g. why std::move take universal reference?.
edit clarify question, i'm asking why overload (2) here necessary, , use case it.
ok since @vsoftco asked concise use case here's refined version (using idea of having "my_forward" see wich overload gets called).
i interpret "use case" providing code sample without prvalue not compile or behave differently (regardless of usefull or not).
we have 2 overloads for std::forward
#include <iostream> template <class t> inline t&& my_forward(typename std::remove_reference<t>::type& t) noexcept { std::cout<<"overload 1"<<std::endl; return static_cast<t&&>(t); } template <class t> inline t&& my_forward(typename std::remove_reference<t>::type&& t) noexcept { std::cout<<"overload 2"<<std::endl; static_assert(!std::is_lvalue_reference<t>::value, "can not forward rvalue lvalue."); return static_cast<t&&>(t); } and have 4 possible use cases
use case 1
#include <vector> using namespace std; class library { vector<int> b; public: // && library( vector<int>&& a):b(std::move(a)){ } }; int main() { vector<int> v; v.push_back(1); library a( my_forward<vector<int>>(v)); // & return 0; } use case 2
#include <vector> using namespace std; class library { vector<int> b; public: // && library( vector<int>&& a):b(std::move(a)){ } }; int main() { vector<int> v; v.push_back(1); library a( my_forward<vector<int>>(std::move(v))); //&& return 0; } use case 3
#include <vector> using namespace std; class library { vector<int> b; public: // & library( vector<int> a):b(a){ } }; int main() { vector<int> v; v.push_back(1); library a( my_forward<vector<int>>(v)); // & return 0; } use case 4
#include <vector> using namespace std; class library { vector<int> b; public: // & library( vector<int> a):b(a){ } }; int main() { vector<int> v; v.push_back(1); library a( my_forward<vector<int>>(std::move(v))); //&& return 0; } here's resume
- overload 1 used, without compilation error
- overload 2 used, without compilation error
- overload 1 used, wihtout compilation error
- overload 2 used, without compilation error
note if not use forward
library a( std::move(v)); //and library a( v); you get:
- compilation error
- compile
- compile
- compile
as see, if use 1 of 2 forward overloads, cause not compile 2 out of 4 cases, while if not use forward @ compile 3 out of 4 cases.
Comments
Post a Comment