3l4*_*l4x 10 c++ forward rvalue lvalue stdmove
因此,我想练习的用法,std::forward并创建了Test具有2个构造函数的类。1个带T&,另一个带T&&作为过载。T&打印左值,并T&&打印右值,所以我知道正在使用哪个构造函数。我在堆栈上创建了2个类的实例,令我惊讶的是,这两个实例都使用了T&&重载。
#include <iostream>
#include <type_traits>
#include <utility>
template <class T> auto forward(T &&t) {
if constexpr (std::is_lvalue_reference<T>::value) {
return t;
}
return std::move(t);
}
template <class T> class Test {
public:
Test(T &) { std::cout << "lvalue" << std::endl; };
Test(T &&) { std::cout << "rvalue" << std::endl; };
};
int main() {
int x = 5;
Test<int> a(forward(3));
Test<int> b(forward(x));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用原始std::forward函数并实现它,但两次都显示了rvalue x2。我究竟做错了什么?
Nat*_*ica 14
您的问题源于的返回类型forward。您使用auto返回类型将不会为您得出参考。这意味着当您返回时,无论它从哪个分支返回,都将按值返回,这意味着您具有prvalue。
您需要的是decltype(auto)根据返回语句返回一个右值或左值引用。使用
template <class T> decltype(auto) forward(T &&t) {
if constexpr (std::is_lvalue_reference<T>::value)
return t;
else
return std::move(t);
}
Run Code Online (Sandbox Code Playgroud)
给你输出:
rvalue
lvalue
Run Code Online (Sandbox Code Playgroud)