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

为什么rvalues引用变量不是rvalue?

商和颂
2023-03-14

假设一个函数有两个重载

void f(T&&); // #1
void f(T&);  // #2

然后在另一个函数的主体中

void g(T&& t) 
{ 
  f(t);  // calls #2
}

过载<代码>f(T

这让我非常惊讶。一个带有签名f(T的函数

使这成为可能的C规则是什么?是T


共有3个答案

牧宁
2023-03-14

在g()中,t是一个命名变量。所有命名变量都是左值。如果T是模板类型,则可以使用std::forward将变量转发到f()。这将调用与传递给g()的类型相同的类型

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

如果T不是模板类型,而只是类型,则可以使用std::move

g(T&& t) { f(std:move(t)); }
费子濯
2023-03-14

当您按名称引用变量时,总是得到左值。此规则没有例外,但请注意,它不适用于预处理器宏、枚举器或非类型模板参数,这些参数都不是通常意义上的变量。

我认为,虽然这种行为起初似乎没有意义,但当你更仔细地考虑时,它确实有意义,而且是正确的行为。首先,我们应该注意到,价值范畴显然是表达式的属性,而不是对象本身的属性。这是显而易见的,因为从未创建新对象,而只是创建一个引用给定对象的右值表达式。那么我们应该明白:

  • 如果表达式是左值,则通常意味着该表达式引用的对象的值可以或将在以后通过同一范围内的同一表达式进行访问。这是通过命名变量访问对象时的默认假设

因此,引用对象的表达式的值类别是相对的;这取决于特定的表达式和范围<代码>标准::move表示您不想在同一范围内再次访问对象的值,从而允许被调用函数将其值移出该对象。然而,当被调用函数访问rvalue引用的名称时,该值在函数调用期间是永久的;函数可以在任何时候将值移出该对象,也可以根本不移出,但无论如何,它可能会在参数初始化之后在主体内访问它。

在此示例中:

void f(Foo&& foo) { /* use foo */ }
void g() {
    Foo foo;
    f(std::move(foo));
}

尽管g中的std::mobile(foo)和被调用者中的参数foo引用同一个对象,但该对象的值即将在st点消失d::在g中移动,而在f中,该对象的值预计将通过foo访问,可能在f结束前多次访问。

调用ref限定成员函数时也存在类似的情况。

struct Foo {
    void f() &;
    void f() &&;
    void g() && {
        f(); // calls lvalue-qualified f
    }
};
void h() {
    Foo().g();
}

这里,Foo()的值即将从h()中消失;完整表达式后将不可用。然而,在Foo::g()的主体中,它是永久的,直到g()结束<代码>*这可以可靠地访问同一对象的值。因此,很自然地,当调用重载时,它应该调用期望为左值的重载,并且不应该从g()中窃取该值,因为g()可能仍然想要访问它。

阮阳曦
2023-03-14
匿名用户

自动被视为Rvalue的对象是没有名称的对象,以及(很快)将没有名称的对象(在返回值的情况下)。

<代码>T

rValue之所以是这些东西,是因为在使用点之后引用它们几乎是不可能的。

<代码>T

它是右值引用类型的事实仅在其构造过程中才重要,如果您执行dectype(variable_name)。否则它只是引用类型的另一个左值。

移动(t)执行返回static\u cast

控制这一点的规则是用C标准中的standardese编写的。复制/粘贴它们并没有那么有用,因为它们不那么容易理解。

第一条一般规则是,当您从函数返回命名值时,或当值没有名称时,或当函数显式返回右值引用时,会得到隐式移动(即绑定到右值引用参数的参数)。

其次,只有右值引用和常量

第三,当直接绑定到构造函数外部的引用时,临时值的引用生命周期扩展发生。(

第四,<代码>T

最后,T

 类似资料:
  • 问题内容: 什么是Java中的对象引用变量? 参考变量是否保存对象的内存地址? 我很困惑。请说明一下。 问题答案: 我不确定我是否有能力正确回答这个问题,但是… 对象是类的实例,它存储在内存中的某些位置 引用是用来描述指向对象所在的内存位置的指针的。 变量是一种可以访问应用程序中该内存位置的方法(其值为“变量”)。尽管变量只能指向单个内存地址(如果不为空),则在应用程序的整个生命周期中,它可能会更

  • 在C++中引用变量的简单定义是什么?

  • 我正在学习结构化绑定声明。我的理解是,

  • 问题内容: 我读了这个问题不可变对象,并留下了关于不可变对象,并最终场一个问题: 为什么我们需要不可变类中的实例变量为最终变量? 例如,考虑以下不可变的类: 如果在上面的代码中没有set方法,而实例变量仅在构造函数中设置,为什么要求将实例变量声明为final? 问题答案: 有没有 要求 这样做的变量。但是,当您确实明确打算永远不更改变量时,通常这样做是一种好习惯,因为这不仅可以使变量避免错别字或其

  • 我有以下代码 我已经阅读了(MSDN) 关键字<code>constexpr</code>在C 11中引入,并在C 14中进行了改进。它表示常量表达式。与<code>const</code>一样,它可以应用于变量,因此如果任何代码试图修改值,就会引发编译器错误。 阅读后,我认为可以使用代替,但是对于上面的代码,我收到一个编译器错误,指出 当 被 替换时,它可以正常工作。我不理解这种行为;有人能说出

  • 问题内容: 为什么全局变量是不好的?[closed] 问题答案: 这与Python无关。全局变量在任何编程语言中都是不好的。 但是,全局常量在概念上与全局变量并不相同。全局常数完全无害。只是在Python中没有强制性差异,只有约定是。 它们不好的原因是它们使函数具有隐藏的(非显而易见的,令人惊讶的,难以检测的)副作用,从而导致复杂性的增加,并有可能导致产生Spaghetti代码。 但是,即使在函数