c++11:std::forward的微妙之处:身份真的有必要吗? [英] c++11: subtlety of std::forward: Is identity really necessary?

查看:33
本文介绍了c++11:std::forward的微妙之处:身份真的有必要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设置了一个测试用例来了解完美转发.

I set up a test case to learn about perfect forwarding.

std::string inner(const std::string& str ) {
return "const std::string&";
}
std::string inner(std::string& str ) {
    return "std::string&";
}
std::string inner(const std::string&& str ) {
    return "const std::string&&";
}
std::string inner(std::string&& str ) {
    return "std::string&&";
}

template <typename T> void outer(T&& t) {
  std::cout << "t: " << t << std::endl;
  std::cout << "perfect forward: " << inner(std::forward<T>(t)) << std::endl;
  std::cout << std::endl;
}

void PerfectForwarding()
{
     outer("literal");
     outer(lvalue);
     outer(constlvalue);
     outer(rvalue());
     outer(constrvalue());
}

std::forward 按预期工作.当我在没有身份的情况下实现自己的前向函数时,有趣的行为出现了:

std::forward works as expected. The interesting behavior emerges when I implement my own forward function without identity:

template <typename T> T&& MyForward(T& t)
{
   return ((T&&)t);
}

在外部用 MyForward 替换 std::forward 给出完全相同的结果!这种行为引出了一个问题,为什么要使用身份?

Replacing std::forward with MyForward in outer gives the exact same result! The behavior begs the question why identity is used?

编译器VS2010

更新 1:关于防止类型推导

Update 1: In reference to preventing type deduction

AFAIK,特殊类型扣除规则仅在 T&& 上激活.注意forward的定义,forward(typename identity::type&t).参数类型只有一个 &.事实上,在我将 MyForward 更改为使用身份并省略 (T&&) 转换后,该示例无法编译.从表面上看,从左值到右值的转换似乎使向前工作.

AFAIK, the special type deduction rule is only activated on T&&. Note the definition of forward, forward(typename identity<T>::type& t). The argument type has only one &. In fact, after I changed MyForward to use identity, and leave out the (T&&) casting, the example does not compile. On the surface, the casting from lvalue to rvalue seems to make the forward work.

更新 2:在 ideone.com 上使用 GCC 4.5 进行测试,行为相同.

Update 2: tested on ideone.com with GCC 4.5, same behavior.

推荐答案

remove_reference(identity 在旧版的草稿中,但改为remove_reference) 用于防止类型推导:std::forward 使用显式类型参数.否则将编译以下内容:

remove_reference<T> (identity was in an old version of the draft, but was changed to remove_reference) is used to prevent type deduction: std::forward only works with an explicit type parameter. Otherwise the following would compile:

std::forward(t)

...但它不会做正确的事情.

... but it would not do the right thing.

关于左值/右值的问题,请注意有两个std::forward 的重载:一个用于左值,另一个用于右值.

Regarding the issue with lvalues/rvalues, please do notice that there are two overloads of std::forward: one for lvalues, another for rvalues.

事实上,给出的 MyForward 实现更像是 std::move:它将左值转换为右值(不同的是,move 也接受右值).

In fact, the MyForward implementation given is more like std::move: it turns lvalues into rvalues (the difference is that move accepts rvalues as well).

这篇关于c++11:std::forward的微妙之处:身份真的有必要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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