std::forward
最常见的用法是完善转发转发(通用)引用,例如
template<typename T>
void f(T&& param)
{
g(std::forward<T>(param)); // perfect forward to g
}
这里 param
是一个 lvalue
,而 std::forward
最终将其转换为右值或左值,具体取决于参数的内容那是有界的。
看definition of std::forward
from cppreference.com我看到还有一个 rvalue
重载
template< class T >
T&& forward( typename std::remove_reference<T>::type&& t );
谁能告诉我为什么 rvalue
重载?我看不到任何用例。如果你想传递一个右值给一个函数,你可以直接传递它,不需要在它上面应用 std::forward
。
这与 std::move
不同,我明白为什么还需要一个 rvalue
重载:您可能会处理您不知道的通用代码您正在传递什么,并且您希望无条件支持 move 语义,请参见例如Why does std::move take a universal reference? .
编辑为了澄清这个问题,我问为什么overload (2) from here是必要的,并且是一个用例。
最佳答案
好的,因为@vsoftco 要求简洁的用例,这里有一个改进的版本(使用他的想法让“my_forward”实际看到调用了重载)。
我通过提供一个代码示例来解释“用例”,如果没有prvalue,它不会编译或行为不同(不管这是否真的有用)。
我们有 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 an rvalue as an lvalue.");
return static_cast<T&&>(t);
}
我们有 4 个可能的用例
用例 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;
}
用例 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;
}
用例 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;
}
用例 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;
}
这是一份简历
- 使用了Overload 1,没有它你会得到编译错误
- 使用了 Overload 2,没有它会出现编译错误
- 使用了Overload 1,没有它你会得到编译错误
- 使用了Overload 2,没有它你会得到编译错误
注意,如果我们不使用forward
Library a( std::move(v));
//and
Library a( v);
你得到:
- 编译错误
- 编译
- 编译
- 编译
如您所见,如果您只使用两个 forward
重载之一,则基本上导致无法编译 4 种情况中的 2 种,而如果您不使用 forward
4 种情况下你只能编译 3 种。
关于c++ - 有纯右值的 std::forward 用例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29859696/