什么样的问题不转发通用引用? [英] What kind of problems for not forwarding universal reference?

查看:117
本文介绍了什么样的问题不转发通用引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,在C ++ 11中,通用引用应该总是使用 std :: forward ,但我不知道什么样的问题如果不使用 std :: forward ,可能会发生。

  ; T> 
void f(T& x);
{
//如果在没有std :: forward< T>(x)的情况下使用x会怎么样?
}

您能介绍一下这种情况下可能发生的问题吗? 始终使用 > std :: forward 通用引用。相反,在通用引用的函数中使用 std :: forward 可能是危险的。看看下面的例子:

  template< typename T> 
auto make_pair(T& t)
{
return std :: make_tuple(std :: forward T(t),std :: forward T ; // BAD
}

如果您使用 make_pair (std :: string {foobar}),结果是反直觉的,因为从同一对象移动两次。






更新:这里是另一个例子,显示使用通用引用真的有意义 / em>:

  template< typename Range,typename Action> 
void foreach(Range&&&&&&&&&&&range)
{
using std :: begin;
using std :: end;
for(auto p = begin(range),q = end(range); p!= q; ++ p){
action(* p);
}
}




  • em> range 是一个通用引用 ,因此调用者可以使用临时容器和动作 foreach ,调用< 成员函数。

  • a 作为动作。

  • 使用 std :: forward


As far as I know, in C++11, universal reference should always be used with std::forward, but I am not sure of what kind of problem can occur if std::forward is not used.

template <T>
void f(T&& x);
{
    // What if x is used without std::forward<T>(x) ?
}

Could you provide some illustrations of problems that could occur in this situation ?

解决方案

There is no such rule to always use std::forward with universal references. On the contrary, it can be dangerous to use std::forward all over the place in functions with universal references. Take a look at the following example:

template <typename T>
auto make_pair(T&& t)
{
    return std::make_tuple(std::forward<T>(t), std::forward<T>(t)); // BAD
}

If you call this function with make_pair(std::string{"foobar"}), the result is counter-intuitive, because you move from the same object twice.


Update: Here is another example to show, that it really makes sense to use universal references without perfect forwarding:

template <typename Range, typename Action>
void foreach(Range&& range, Action&& action)
{
    using std::begin;
    using std::end;
    for (auto p = begin(range), q = end(range); p != q; ++p) {
        action(*p);
    }
}

  • It's good that range is a universal reference, so that the caller can use foreach with a temporary container and an action, that's calls a non-const member function on the elements.
  • It's good that action is a universal reference, so that the caller can pass a mutable lambda expression as action.
  • And it would be wrong to use std::forward for range or for action.

这篇关于什么样的问题不转发通用引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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