int t = 10; // t为左值 ++t; // t为左值,没有拷贝,这就是为什么 ++t 比 t++ 高效 t++; // t为右值,因为加之前的值是个将亡值,是个 t_copy,是个临时变量 int &&r = t; // 错误,右值不能绑定左值。
std::move()
实现代码
1 2 3 4 5 6 7 8 9
/** * @brief Convert a value to an rvalue. * @param __t A thing of arbitrary type. * @return The parameter cast to an rvalue-reference to allow moving it. */ template<typename _Tp> constexprtypename std::remove_reference<_Tp>::type&& move(_Tp&& __t)noexcept { returnstatic_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
intmain(){ int a = 1; int b = 2; constint c = 1; constint d = 0; int &e = a; int &f = b; constint &g = c; constint &h = d; WithoutPerfectForward(a); // l + r = l WithoutPerfectForward(move(b)); // r + r = r WithoutPerfectForward(c); // const l + r = l WithoutPerfectForward(move(d)); // const r + r = r WithoutPerfectForward(e); // l ref + r = l WithoutPerfectForward(move(f)); // r ref + r = r WithoutPerfectForward(g); // const l ref + r = l WithoutPerfectForward(move(h)); // const r ref + r = r }
intmain(){ int a = 1; int b = 2; constint c = 1; constint d = 0; int &e = a; int &f = b; constint &g = c; constint &h = d; WithoutPerfectForward(a); // l + r WithoutPerfectForward(move(b)); // r + r WithoutPerfectForward(c); // const l + r WithoutPerfectForward(move(d)); // const r + r WithoutPerfectForward(e); // l ref + r WithoutPerfectForward(move(f)); // r ref + r WithoutPerfectForward(g); // const l ref + r WithoutPerfectForward(move(h)); // const r ref + r }
结果:
1 2 3 4 5 6 7 8 9
@└────> # ./a.out int & called! int & called! const int & called! const int & called! int & called! int & called! const int & called! const int & called!
可以看到虽然在函数 WithoutPerfectForward 中是右值,但是传给下一个函数的时候又默认都是左值了。虽然参数 t 是右值类型的,但此时 t 在内存中已经有了位置,所以 t 其实是个左值。
intmain(){ int a = 1; int b = 2; constint c = 1; constint d = 0; int &e = a; int &f = b; constint &g = c; constint &h = d; WithoutPerfectForward(a); // l + r WithoutPerfectForward(move(b)); // r + r WithoutPerfectForward(c); // const l + r WithoutPerfectForward(move(d)); // const r + r WithoutPerfectForward(e); // l ref + r WithoutPerfectForward(move(f)); // r ref + r WithoutPerfectForward(g); // const l ref + r WithoutPerfectForward(move(h)); // const r ref + r }
结果:
1 2 3 4 5 6 7 8 9
@└────> # ./a.out int & called! int && called! const int & called! const int && called! int & called! int && called! const int & called! const int && called!
/** * @brief Forward an lvalue. * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". */ template<typename _Tp> constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type& __t)noexcept { returnstatic_cast<_Tp&&>(__t); }
/** * @brief Forward an rvalue. * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". */ template<typename _Tp> constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type&& __t)noexcept { static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument" " substituting _Tp is an lvalue reference type"); returnstatic_cast<_Tp&&>(__t); }