当前位置: 首页 > 知识库问答 >
问题:

转发引用不是推导成R值引用吗?[副本]

魏元白
2023-03-14

我有一个关于转发推荐信的具体问题。(我认为)我理解R值引用和std::move,但理解转发引用有困难:

#include <iostream>
#include <utility>

template <typename T> class TD; // from "Effective Modern C++"

void consume(const int &i) { std::cout << "lvalue\n"; }
void consume(int &&i)      { std::cout << "rvalue\n"; }

template <typename T>
void foo(T&& x) {
//    TD<decltype(x)> xType; - prints int&&
    consume(x);
}

int main() {
    foo(1 + 2);
}

tint,这很好。如果xint&类型,为什么它打印“lvalue”,而我们需要std::forward?我的意思是,从int&&const int&的转换在哪里?

共有2个答案

狄兴邦
2023-03-14

类型和值类别是两个独立的东西。x的类型是int&,但x是变量的名称,x是一个lvalue表达式,它不能绑定到int&(但可以绑定到const int&)。

以下表达式是lvalue表达式:

  • 变量、函数、模板参数对象(自C++20起)或数据成员的名称,无论类型如何,如std::cin或std::endl。即使变量的类型是rvalue引用,由其名称组成的表达式也是lvalue表达式;

std::forward用于根据转发引用参数的原始值类别将操作数转换为rvalue或lvalue。这意味着,当lvalueint传递给foo时,t被推导为int&,那么std::forward (x) 将是lvalue表达式;当rvalueint传递给foo时,t被推导为int,那么std::forward (x) 将是rvalue表达式。因此std::forward可用于保留原始转发引用参数的值类别。

杜晨朗
2023-03-14

呼叫:

consume(x);

将始终选择consumer()的lvalue引用重载,因为表达式x是一个lvalue。这与x的推导类型无关。

但是,通过调用consumer()作为:

consume(std::forward<T>(x));

如果传递给foo()(即包装函数)的参数的值类别是一个rvalue,它将选择rvalue引用重载-即,它将该值类别传播到嵌套调用。

 类似资料:
  • 我仍然被那些为了支持移动和转发而发明的规则弄糊涂了。有一件事我还不太确定: 转发引用是否只是rvalue引用(应用了引用折叠规则)? 如果它是一个rvalue引用,那么为什么函数: 不仅接受rvalues,还接受lvalues?

  • 问题内容: 考虑一下我要调用的函数的副作用,而不是返回值(例如打印到屏幕,更新GUI,打印到文件等)。 现在,使用列表推导功能将此功能称为Pythonic: 请注意,我不会将列表保存在任何地方 还是我应该这样称呼这个函数: 哪个更好?为什么? 问题答案: 这样做是非常反Python的,任何经验丰富的都会为你带来麻烦。中间列表在创建之后就被丢弃了,它可能非常大,因此创建起来很昂贵。

  • 作为R新手,我很难引导ICC输出。我首先设法使用ICC包计算“正常”ICC,没有任何问题(ICCbare(subject,variable,ICC)),但当我试图得到一些自举估计值时,情况变得更糟。。。 我一开始是 并在引导程序中输入icc_引导,如下所示: 然而,我得到一个错误消息说"未定义的列选择",我哪里出错了? 这是我的一个小数据输出

  • 本文向大家介绍C++11右值引用和转发型引用教程详解,包括了C++11右值引用和转发型引用教程详解的使用技巧和注意事项,需要的朋友参考一下 右值引用 为了解决移动语义及完美转发问题,C++11标准引入了右值引用(rvalue reference)这一重要的新概念。右值引用采用T&&这一语法形式,比传统的引用T&(如今被称作左值引用 lvalue reference)多一个&。 如果把经由T&&这一

  • 我正在尝试使用创建一个6乘12的矩阵 虽然这样可以工作,但问题是内部数组实际上都引用了相同的对象。 我希望(并且期望)的值为。 如何强制填充给定参数的按值复制(例如:是我的例子中的参数)而不是按引用复制?

  • 我刚开始写CSV文件,有一个场景我找不到答案。我需要生成一个没有标题的CSV文件,其中数字值不带引号,字符串带引号。例如-71,72,“初始”,“2020-10-01”。 我使用的CSVWriter构造函数: 我试图用双引号填充字符串值,但这不起作用。 输出为: 我必须。toString ID,因为writeAll()和writeNext()函数似乎采用字符串数组,并且不接受任何类型的数组。 我想