C++ 不理解左值的双重转发-按值传递时
为什么不是3,3?这个左值在什么时候变成右值并从右值移动 这个左值在什么时候变成右值并从右值移动 在第一次调用C++ 不理解左值的双重转发-按值传递时,c++,c++11,rvalue-reference,perfect-forwarding,C++,C++11,Rvalue Reference,Perfect Forwarding,为什么不是3,3?这个左值在什么时候变成右值并从右值移动 这个左值在什么时候变成右值并从右值移动 在第一次调用proxy时,将v转换为右值,然后在传递到real\u func时将其从移动 size: 3 size: 0 void multicast_func(向量v){ //std::forward的返回类型是T&&,即这里的vector&& //对于返回类型为对objec的右值引用的函数,返回值为右值 //这意味着v被转换为右值并传递给代理 代理(real_func,std::forward
proxy
时,将v
转换为右值,然后在传递到real\u func
时将其从移动
size: 3
size: 0
void multicast_func(向量v){
//std::forward的返回类型是T&&,即这里的vector&&
//对于返回类型为对objec的右值引用的函数,返回值为右值
//这意味着v被转换为右值并传递给代理
代理(real_func,std::forward(v));
//v在作为参数传递给real_func时已被移动
代理(real_func,std::forward(v));
}
proxy
中的用法是std::forward
的一般用法;根据参数是左值还是右值,模板参数将被推断为T&
或T
。对于T&
std::forward
将返回左值,对于T
std::forward
将返回右值,因此保留值类别。当指定模板参数时,这样的容量将丢失
这个左值在什么时候变成右值并从右值移动
在第一次调用proxy
时,将v
转换为右值,然后在传递到real\u func
时将其从移动
size: 3
size: 0
void multicast_func(向量v){
//std::forward的返回类型是T&&,即这里的vector&&
//对于返回类型为对objec的右值引用的函数,返回值为右值
//这意味着v被转换为右值并传递给代理
代理(real_func,std::forward(v));
//v在作为参数传递给real_func时已被移动
代理(real_func,std::forward(v));
}
proxy
中的用法是std::forward
的一般用法;根据参数是左值还是右值,模板参数将被推断为T&
或T
。对于T&
std::forward
将返回左值,对于T
std::forward
将返回右值,因此保留值类别。当指定模板参数时,这种容量将丢失。std::forward
用于通用引用
multicast_func
的参数不是通用的参考,因此std::forward
没有意义:
void multicast_func(vector<int> v) {
// the return type of std::forward is T&&, i.e. vector<int>&& here
// for functions whose return type is rvalue reference to objec, the return value is an rvalue
// that means v is converted to an rvalue and passed to proxy
proxy(real_func, std::forward<vector<int>>(v));
// v has been moved when passed to real_func as argument
proxy(real_func, std::forward<vector<int>>(v));
}
void multicast_func(向量v){
代理(real_func,std::forward(v));
代理(real_func,std::forward(v));
}
在这种情况下,它的有效作用类似于
std::move
(因为模板参数不是(左值)引用)。std::forward
旨在与通用引用一起使用
multicast_func
的参数不是通用的参考,因此std::forward
没有意义:
void multicast_func(vector<int> v) {
// the return type of std::forward is T&&, i.e. vector<int>&& here
// for functions whose return type is rvalue reference to objec, the return value is an rvalue
// that means v is converted to an rvalue and passed to proxy
proxy(real_func, std::forward<vector<int>>(v));
// v has been moved when passed to real_func as argument
proxy(real_func, std::forward<vector<int>>(v));
}
void multicast_func(向量v){
代理(real_func,std::forward(v));
代理(real_func,std::forward(v));
}
在这种情况下,它的作用实际上类似于
std::move
(因为模板参数不是(左值)引用)。std::forward
,当没有给定引用类型时,将提供的对象强制转换为右值。这意味着第一次呼叫
void multicast_func(vector<int> v) {
proxy(real_func, std::forward<vector<int>>(v));
proxy(real_func, std::forward<vector<int>>(v));
}
由于您为
T
传递了std::vector
,这意味着它将返回一个std::vector&&
。因此,即使v
是左值,它也会转换为右值。如果要保持v
的左值,则需要使用std::vector&
。这将为您提供std::vector&&&
和引用colapse规则,并将其转换为std::vector&
,给您留下一个左值。std::forward
,当未提供引用类型时,将提供的对象强制转换为右值。这意味着第一次呼叫
void multicast_func(vector<int> v) {
proxy(real_func, std::forward<vector<int>>(v));
proxy(real_func, std::forward<vector<int>>(v));
}
由于您为
T
传递了std::vector
,这意味着它将返回一个std::vector&&
。因此,即使v
是左值,它也会转换为右值。如果要保持v
的左值,则需要使用std::vector&
。这将为您提供std::vector&&&
和引用colapse规则,并将其转换为std::vector&
,给您留下一个左值。在代码中调用的std::forward
的原型是:
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type& t ) noexcept;
模板
constexpr T&forward(typename std::remove_reference::type&T)无异常;
当使用非引用类型调用时,它会有效地从参数中生成一个右值引用,而不是从中移动
std::vector
从中移出后保证为空,因此size
变为0。在代码中调用的std::forward
的原型是:
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type& t ) noexcept;
模板
constexpr T&forward(typename std::remove_reference::type&T)无异常;
当使用非引用类型调用时,它会有效地从参数中生成一个右值引用,而不是从中移动
std::vector
在从中移动后保证为空,因此size
变为0。在proxy
的第一次调用中,参数vector v
(在functionreal\u func
中)是从右值移动构造的,因此v
(在functionmulticast\u func
中)是空的。但是如果将参数表的类型更改为
cosnt vector&
,结果将是3,3。因为尚未调用移动构造函数
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type& t ) noexcept;
void real_func(常量向量&v){
cout在proxy
的第一次调用中,参数vector v
(在functionreal\u func
中)是从右值移动构造的,因此v
(在functionmulticast\u func
中)