C ++ 11完美的转发和参考折叠 [英] C++11 perfect forwarding and reference collapsing

查看:90
本文介绍了C ++ 11完美的转发和参考折叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

template<typename T>
void foo(T&& param){ //In this case && is called universal reference
    std:string tmp = std::forward<string>(param);
}

我的问题是,是否可以推断出通用引用类型,为什么我仍然需要向前调用?
为什么即使不推定t的类型,也不会调用tmp的正确c'tor.

My question is if universal reference type can be deduced why do I still need to call forward ?
Why without forwarding tmp's correct c'tor won't be called even if T's type was deduced.

我的第二个问题是关于参考折叠规则:

My second question is about reference collapsing rules:

  1. A& &&变为A&
  2. A&& &&变为A&&
  1. A& && becomes A&
  2. A&& && becomes A&&

因此,根据此规则并考虑通用参考,为什么std :: forward签名不能如下所示:

so according this rules and taking in account universal reference why std::forward signature can't be as follows:

template<class T> 
T&& forward(T&& arg){
    return static_cast<T&&>(arg);
}

根据上面的规则,如果T的类型是右值引用,它将折叠为右值引用;如果T的类型是左值引用,它将折叠为左值引用.
那么为什么std::forward有两个不同的签名,一个用于左值引用,一个用于右值引用,我是否遗漏了一些东西?

According to the rules from above if T's type is rvalue reference it will collapse to rvalue reference , if T's type is lvalue reference it will collapse to lvalue reference.
So why std::forward have two different signatures one for lvalue reference and one for rvalue reference am I missing something ?

推荐答案

我的问题是,是否可以推断出通用引用类型,为什么我仍然需要进行前转?

My question is if universal reference type can be deduced why do I still need to call forward ?

因为为参数param命名后它就是一个左值,即使该函数是用右值调用的,因此除非您使用forward<T>,否则不会将其作为右值转发

Because as soon as you give a name to the parameter param it is an lvalue, even if the function was called with an rvalue, so it wouldn't be forwarded as an rvalue unless you use forward<T>

即使不推定T的类型,为什么不转发tmp的正确c'tor也不会被调用.

Why without forwarding tmp's correct c'tor won't be called even if T's type was deduced.

因为param是左值.要还原传递给foo的参数的值类别,您需要将其强制转换回string&string&&,这意味着您需要知道推导为T的类型,并使用forward进行操作.演员.

Because param is an lvalue. To restore the value category of the argument passed to foo you need to cast it back to string& or string&& which means you need to know the type T was deduced as, and use forward to do the cast.

那么为什么std::forward有两个不同的签名,一个用于左值引用,一个用于右值引用,我是否缺少某些东西?

So why std::forward have two different signatures one for lvalue reference and one for rvalue reference am I missing something ?

它已由 http://更改. www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html

http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html 建议版本的问题是,如果您说forward<string>,则不会推导参数T,因此它不能用作转发引用,这意味着T&&不能绑定到左值,并且它必须能够绑定到左值以使forward<string>(param)起作用,因为param是在那里的左值.

The problem with your suggested version is that if you say forward<string> then the parameter T is not deduced so doesn't function as a forwarding reference, which means that T&& can't bind to an lvalue, and it needs to be able to bind to an lvalue in order for forward<string>(param) to work, because param is an lvalue there.

这篇关于C ++ 11完美的转发和参考折叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆