需要Meyers有效的C++;窗口小部件右值示例说明 我有一个小的C++问题。< /P> RS< 是一个RValk引用(意味着它将优先匹配RADORT参数),但是在移动构造函数块中,变量 RHS本身仍然会作为LValk,从而优先匹配接受左值引用的函数 void test(Widget&&) { std::cout << "test(Widget&&): called\n"; } void test(Widget&) { std::cout << "test(Widget&): called\n"; } Widget::Widget(Widget&& rhs) { // here, `rhs` is an lvalue, not an rvalue even though // its type is declared to be an rvalue reference // for example, this will match `test(Widget&)` // rather than the `test(Widget&&)` overload, which may be // a bit counter-intuitive test(rhs); // if you really want to match `test(Widget&&)` // you must use `std::move` to "wrap" the variable // so that it can be treated as an rvalue test(std::move(rhs)); } 无效测试(Widget&&{std::cout

需要Meyers有效的C++;窗口小部件右值示例说明 我有一个小的C++问题。< /P> RS< 是一个RValk引用(意味着它将优先匹配RADORT参数),但是在移动构造函数块中,变量 RHS本身仍然会作为LValk,从而优先匹配接受左值引用的函数 void test(Widget&&) { std::cout << "test(Widget&&): called\n"; } void test(Widget&) { std::cout << "test(Widget&): called\n"; } Widget::Widget(Widget&& rhs) { // here, `rhs` is an lvalue, not an rvalue even though // its type is declared to be an rvalue reference // for example, this will match `test(Widget&)` // rather than the `test(Widget&&)` overload, which may be // a bit counter-intuitive test(rhs); // if you really want to match `test(Widget&&)` // you must use `std::move` to "wrap" the variable // so that it can be treated as an rvalue test(std::move(rhs)); } 无效测试(Widget&&{std::cout,c++,c++11,rvalue-reference,lvalue,C++,C++11,Rvalue Reference,Lvalue,此外,还有一条注释:“rhs是一个左值,尽管它有一个右值引用类型” 老实说,我什么都不懂。“rhs是左值,但它的类型是右值引用”是什么意思?请记住,这里有两个不同的东西: 一个与变量类型相关:有两种类型的引用:左值引用(&)和右值引用(&&) 这决定了函数优先接受的内容,并且始终是“明显的”,因为您可以从类型签名中读取它(或使用decltype) 另一个是表达式(或值)的属性:表达式可以是左值或右值() 此属性没有直接在代码中显示(但有一条经验法则,请参见下文),但您可以在重载解析中看到其效果

此外,还有一条注释:“rhs是一个左值,尽管它有一个右值引用类型”


老实说,我什么都不懂。“rhs是左值,但它的类型是右值引用”是什么意思?

请记住,这里有两个不同的东西:

  • 一个与变量类型相关:有两种类型的引用:左值引用(
    &
    )和右值引用(
    &&

    这决定了函数优先接受的内容,并且始终是“明显的”,因为您可以从类型签名中读取它(或使用
    decltype

  • 另一个是表达式(或值)的属性:表达式可以是左值或右值()

    此属性没有直接在代码中显示(但有一条经验法则,请参见下文),但您可以在重载解析中看到其效果。特别是,

    • 左值参数更喜欢绑定到左值引用参数,而
    • 右值参数更喜欢绑定到右值引用参数
这些属性密切相关(在某种意义上是“双重的”),但它们不一定彼此一致。尤其重要的是要认识到变量和表达式实际上是不同的东西,所以从形式上讲,它们甚至是不可比较的,“苹果对桔子”


< C++中有这样的规则,即使您已经声明了代码> RS< <代码>是一个RValk引用(意味着它将优先匹配RADORT参数),但是在移动构造函数块中,变量<代码> RHS本身仍然会作为LValk,从而优先匹配接受左值引用的函数

void test(Widget&&) { std::cout << "test(Widget&&): called\n"; }
void test(Widget&)  { std::cout << "test(Widget&): called\n"; }

Widget::Widget(Widget&& rhs) {
    // here, `rhs` is an lvalue, not an rvalue even though
    // its type is declared to be an rvalue reference

    // for example, this will match `test(Widget&)`
    // rather than the `test(Widget&&)` overload, which may be
    // a bit counter-intuitive
    test(rhs);

    // if you really want to match `test(Widget&&)`
    // you must use `std::move` to "wrap" the variable
    // so that it can be treated as an rvalue
    test(std::move(rhs));
}

无效测试(Widget&&{std::cout简短的解释:p

Widget(Widget&& rhs);

是移动构造函数。它将接受右值作为参数。在移动构造函数的定义中,您可以使用名称rhs引用另一个小部件,因此它是左值。

并且您可以使用
std::move()
删除其名称(将其转换为右值)。“即使已将
rhs
声明为右值引用[…],变量
rhs
本身仍将作为左值“我认为在Standardese中,人们会说,即使您声明了一个名为
rhs
且类型为'rvalue reference to
Widget
'的变量/参数,引用该变量的表达式也是左值表达式。类似地,“if the expression have name”表达式没有名称。表达式可以包含名称/“名称”(标识符作为表达式,即id表达式)可以是表达式。标识符表达式是左值,除非它引用枚举数。(但我挑剔,+1)我是在引用别人的话,但是,是的,把表达式和变量等同起来在技术上是不正确的。我不想用太多的标准把答案难住:)好吧,谢谢你们的解释,伙计们,我终于明白了!大家都很荣幸。