【问题标题】:Move from *this in an rvalue method?在右值方法中从 *this 移动?
【发布时间】:2010-06-12 12:19:57
【问题描述】:

在 C++11 中,可以根据表示调用方法的对象的表达式是左值还是右值来重载方法。如果我从通过右值调用的方法返回*this,我是否需要从*this 显式地move

Foo Foo::method() &&
{
    return std::move(*this);   // Is this move required or not?
}

不幸的是,我不能简单地在我的编译器上测试这个,因为 g++ 还不支持这个功能:(

【问题讨论】:

  • 我希望move 是必需的,因为this 是一个命名的右值,类似于函数采用右值参数的情况。但不让它成为答案,因为我不能引用它的章节和诗句:)
  • @jalf:我希望移动是必需的,因为通常*E 是一个左值,但谁知道:) 我以前从未听说过命名的右值。你确定吗”? (没有双关语!)
  • 命名右值是一个新术语,用于消除涉及引用的重载调用的歧义。例如如果我们有foo(X& x)foo(X&& x),那么foo(someX) 调用什么,即someXX&X&&?答案是X&,因为someX 有一个名字——它是一个命名的右值,它是一个X&。如果我们调用foo(someX + something),那么它将是X&&,因为表达式没有“名称”。
  • "是 someXX& 还是 X&&?" -> 呃,不是吗?它是一个 X :) 我看不出 someX 除了左值之外什么都不是......

标签: c++ c++11 rvalue-reference


【解决方案1】:

*this 的类型总是一个左值:

§9.3.2 [class.this] p1

在非静态 (9.3) 成员函数的主体中,关键字 this 是一个纯右值表达式,其值是调用该函数的对象的地址。 X 类的成员函数中 this 的类型是 X*。 [...]

§5.3.1 [expr.unary.op] p1

一元*运算符执行间接:应用它的表达式应该是指向对象类型的指针,或指向函数类型的指针,并且结果是一个左值,表示表达式指向的对象或函数。

所以如果你想调用移动构造函数,你需要std::move

下面的代码sn-p表明:

#include <iostream>
#include <utility>

struct test{
  test(){}
  test(test const&){ std::cout << "copy ctor // #1\n"; }
  test(test&&){ std::cout << "move ctor // #2\n"; }

  test f_no_move() &&{ return *this; }
  test f_move() &&{ return std::move(*this); }
};

int main(){
  test().f_no_move(); // #1
  test().f_move(); // #2
}

使用 Clang 3.1(我知道的唯一一个实现 ref-qualifiers 的编译器),我得到以下输出:

$ clang++ -std=c++0x -stdlib=libc++ -pedantic -Wall t.cpp
$ ./a.out
复制 ctor // #1
移动 ctor // #2

【讨论】:

    猜你喜欢
    • 2021-10-26
    • 1970-01-01
    • 2018-03-27
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多