当const引用参数绑定到右值时,它是否保持其“状态”?

阿纳克汉德

T是任意类型。考虑一个带有const[lvalue]引用的函数

void f(const T &obj);

假设此函数在内部调用另一个函数,该函数具有右值引用重载:

void g(T &&obj);

如果我们将右值传递给f,将g调用右值引用重载,还是因为它已经“转换” /绑定到const左值引用而失败了

同样,如果f调用的函数采用T按值的实例

void h(T obj);

并且T具有move构造函数(即T(T &&);),将调用move构造函数,还是将调用copy构造函数?

总而言之,如果我们想确保在调用f右值时,右值引用传递时保持其右值“状态”,我们是否必须为它提供右值引用重载f

黑猫

当您将引用的名称用作表达式时,该表达式始终是左值。无论是左值引用还是右值引用。引用是用左值还是右值初始化也没有关系。

int &&x = 1;
f(x); // Here `x` is lvalue.

所以void f(const T &obj) {...}obj始终是一个左值,不管你通过什么作为参数。

还要注意,值类别是在编译时确定的。由于f不是模板,因此其中每个表达式的值类别都不能取决于您传递的参数。

从而:

如果我们向传递右值f,则将g调用右值引用重载

没有。

如果f调用的函数采用T的实例void h(T obj);并且T具有移动构造函数(即T(T &&);),则将调用移动构造函数

没有。

总而言之,如果我们想确保在调用f右值时,右值引用传递时保持其右值“状态”,我们是否必须为它提供右值引用重载f

提供过载是一种选择。请注意,在这种情况下,您必须显式调用std::move右值重载。

另一种选择是使用转发引用,如Nicol Bolas建议的那样:

template <typename T> void f(T &&t)
{
    g(std::forward<T>(t));
}

在这里,std::forward本质上是作为“有条件的move”。t如果将右值传递给它,它将移动,否则不执行任何操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么 const 临时绑定到右值引用参数?

为什么静态const char * const变量是左值时可绑定到右值引用参数?

将const引用绑定到右值引用

绑定到静态const引用的右值的生命周期

为什么两个const / nonconst左值引用都绑定到右值引用?

左值到右值引用绑定

右值引用绑定到左值

对“ Item * const”类型的引用无法绑定到“ const Item *”类型的右值

为什么const volatile引用不能绑定到右值引用?

为什么我可以在C ++中使用for循环将右值绑定到非const引用?

为什么编译器不能将const int绑定到右值引用?

为什么右值引用类型的模板参数可以绑定到左值类型?

无法将“Node&”类型的非 const 左值引用绑定到“const Node”类型的右值

绑定到参数和返回值const引用的C ++临时对象

用`void *`将右值引用绑定到左值

将非常量左值引用绑定到右值

无法将左值绑定到右值引用

为什么此右值引用绑定到左值?

将右值绑定到左值引用

返回语句将右值引用绑定到左值?

右值引用绑定到std :: function类型的左值

将右值引用绑定到(自动生成的)左值

为什么不允许将右值引用绑定到非const引用,但是却可以在一个对象上调用非const成员函数

std :: async使用绑定到lambda的右值引用

当C ++函数不“移出”右值引用参数时,这是否合理?

禁用GLOBAL INTERRUPT时,中断是否保持其状态?

右值引用如何绑定到幕后的临时值(右值)

当显式更改int的值时,为什么对const int(绑定到int)的引用的值会更改?

为什么可以将右值间接绑定到左值引用,而不能直接绑定呢?