为成员变量分配右值引用

时间:2014-12-21 21:07:30

标签: c++ visual-studio qt rvalue-reference

我正在尝试编写一个有效的方法来将Image(一个QImage - Qt5.3)分配给我班级的成员变量:

void ImageView::setImage(QImage&& image){
    std::cout << &image << std::endl;

    _image = image;
    //_image = std::move(image);

    std::cout << &_image << std::endl;

    _imageAssigned = true;
    updateResizedImage();
    update();
}

我可以使用两行代码,第一行是_image = image;,第二行是_image = std::move(image);。现在我认为第一行应该是完全正常的,并且实际上应该使用QImage的=运算符重载,它采用右值引用,因为图像已经是右值引用。但是,Visual Studio的工具提示向我显示使用了normal =运算符。如果我改为使用第二行,工具提示会显示使用右值的重载。现在我的问题是为什么会这样。我的第一行还不够吗?调用已经是右值参考的变量的移动对我来说似乎是超级的。

我尝试通过输出指针来自己测试(如代码中所示)。现在,无论我使用哪一行,指针都是不同的。这让我感到困惑。看来,我的代码并没有像我想象的那样运行。谁能告诉我我做错了什么?

感谢您的帮助

1 个答案:

答案 0 :(得分:4)

具有名称的对象是左值。声明为QImage&&表示只有一个右值可以绑定到此引用,但引用本身始终是左值:它有一个名称。如果要转发实体的右值,则必须使用std::move()明确指出。如果推导出右值(即,您使用T&&形式的推导模板参数,其中T为模板参数),您将使用std::forward<T>(arg)有条件地转发右值。

image_image的地址当然是不同的,因为它们首先是不同的对象。如果QImage包含具有地址的对象,则可以验证是否使用该地址移动了对象。例如,如果您使用std::vector<T>而不是QImage,则可以使用类似的内容来确定数组是否已被移动:

void f(std::vector<T>&& v) {
    std::cout << (v.empty()? 0: v.data()) << '\n';
    std::vector<T> other;
    other = v; // will be copied
    std::cout << (other.empty()? 0: v.data()) << '\n';
    other = std::move(v); // will be moved
    std::cout << (other.empty()? 0: v.data()) << '\n';
}