首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么编译器不选择rvalue-引用版本的“doesn”?

为什么编译器不选择rvalue-引用版本的“doesn”?
EN

Stack Overflow用户
提问于 2020-04-14 07:09:24
回答 2查看 67关注 0票数 2

我编写了一个类似的std::forward实现,希望找出在这种情况下编译器将选择哪个版本。问题是,似乎永远不会选择rvalue-reference版本。

代码语言:javascript
复制
#include <type_traits>
#include <iostream>
#include <string>
#include <utility>

using std::string;
using std::cout;
using std::endl;
using std::remove_reference;
using std::move;

namespace explicit_return {
template <typename type> type&& forward(typename remove_reference<type>::type&  value) { cout << "cp-"; return static_cast<type&&>(value); }
template <typename type> type&& forward(typename remove_reference<type>::type&& value) { cout << "mv-"; return static_cast<type&&>(value); }
}

void print(string const & value) { cout << "c:" << value << endl; }
void print(string &  value)      { cout << "l:" << value << endl; }
void print(string && value)      { cout << "r:" << value << endl; }

template <typename type> void explicit_print(type && value) {          print(explicit_return::forward<type>(value)); }
template <typename type> void indirect_print(type && value) { explicit_print(explicit_return::forward<type>(value)); }

int main()
{
    string a("perfect");
    indirect_print(a);
    indirect_print(move(a));
    indirect_print("forward");
}

让我们看看输出

代码语言:javascript
复制
cp-cp-l:perfect
cp-cp-r:perfect
cp-cp-r:forward
EN

回答 2

Stack Overflow用户

发布于 2020-04-14 08:11:06

传递给forward<type>的参数是一个变量,因此是l-value

当r值为r值时,您可能会选择带有额外std::move的r值重载或额外转发,例如:

代码语言:javascript
复制
template <typename type> void print_forward2(type&& value)
{
     print(explicit_return::forward<type>(explicit_return::forward<type>(value)));
}

演示

在实践中,我可以想象在tuple中存储参数并重新应用它们(一次),这是与以下内容相关的:

代码语言:javascript
复制
print(std::forward<Ts>(std::get<Ts>(std::move(my_tuple)))...);
票数 1
EN

Stack Overflow用户

发布于 2020-04-14 08:26:29

尽管您已经将indirect_print参数声明为type &&,但它的值类不是rvalue,而是lvalue。任何命名对象都是lvalue。

代码语言:javascript
复制
template <typename type>
void indirect_print(type && value) {
  explicit_print(explicit_return::forward<type>(value)); // `value` is lvalue here
}

这就是为什么您总是调用type&版本的forward

删除explicit_printindirect_print,并将main重写为:

代码语言:javascript
复制
int main()
{
    string a("perfect");

    print(explicit_return::forward<std::string>(a));
    print(explicit_return::forward<std::string>(move(a)));
    print(explicit_return::forward<std::string>("forward"));
}

你会看到不同之处:

代码语言:javascript
复制
cp-r:perfect
mv-r:perfect
mv-r:forward
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61202388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档