c++ - Why there are two signatures of std::forward? -
as stated @ cplusplus.com, std::forward has 2 signatures:
template <class t> t&& forward (typename remove_reference<t>::type& arg) noexcept; template <class t> t&& forward (typename remove_reference<t>::type&& arg) noexcept; the typical use of std::forward preserve rvalueness while passing arguments other functions. let's illustrate example:
void overloaded(int &) { std::cout << "lvalue"; } void overloaded(int &&) { std::cout << "rvalue"; } template <typename t> void fwd(t && t) { overloaded(std::forward<t>(t)); } when call fwd(0), t deduces int (t has type int &&). call std::forward<int>(t). result of call expression of type int && second version of overloaded function selected , program prints "rvalue" standard output.
when call fwd(i) (where int variable), t deduces int& (t has type int &). call std::forward<int&>(t). result of call (after applying reference collapsing rules) expression of type int & first version of overloaded function selected , program prints "lvalue" standard output.
in both these cases use first overload of std::forward (the 1 taking typename remove_reference<t>::type& arg). because if type of t int && binds lvalue reference (because named variable of type "rvalue reference something" lvalue , lvalues can't bind rvalue reference).
question 1:
what second overload of std::forward for? can think of practical example, uses overload taking arg rvalue reference?
question 2:
cplusplus.com says:
both signatures return same as:
static_cast<decltype(arg)&&>(arg)
the problem have that, i'm pretty sure wrong. when try return first overload of std::forward compilation error.
when fwd called int rvalue, calls first overload of std::forward t = int. then, decltype(arg) become int& static_cast<decltype(arg)&&>(arg) collapse static_cast<int&>(arg). return type int && , compilation error:
cannot bind ‘std::remove_reference<int>::type {aka int}’ lvalue ‘int&&’ both overloaded versions of std::forward should return static_cast<t&&>(arg). right?
do think quote cplusplus.com mistake?
class foo {}; auto f = [](){ return foo{}; }; auto g = []()->foo&{ static foo x; return x; }; template<class t> std::false_type is_rvalue( t& ) { return {}; } template<class t> std::true_type is_rvalue( t&& ) { return {}; } template<class t, class f> auto test( f&& f ) { return is_rvalue( std::forward<t>( f() ) ); } int main() { std::cout << test<foo>(f) << "," << test<foo&>(g) << "\n"; } it bit contrived; imagine have factory might produce foo or foo& depending on unimportant details, know want forward based on second type t t&&. know if t not reference, won't produce foo, if t reference might.
Comments
Post a Comment