如果std :: move在&&和&作为参数上用作参数,它会调用它吗?参数?

时间:2015-06-24 23:36:47

标签: c++ c++11

这是我的代码:

#include <iostream>


class carl{
    public:
    int x;

    carl(int y):x(y){

    }


    carl(carl&& other)
    {
    std::cout<<" cons called?"<<std::endl;
    this->x = other.x;
    other.x = 0;
    }


    void operator=(carl&& other){
    std::cout<<"operator called?"<<std::endl;
    this->x = other.x;
    other.x = 0;
    }
};



void funct(carl&& get){
std::cout<<get.x<<std::endl;    
}


int main(int argc, char** argv) {
    carl c(2);
    funct(std::move(c));
    std::cout<<c.x<<std::endl;
    return 0;
}

输出:

2
2

如果我记得,对于特殊成员函数有一个特殊的规则,声明如果一个类声明了一个移动构造函数/运算符,那么该类将不会自动生成复制运算符/构造函数。

根据我的例子,似乎没有调用移动运算符和构造函数,而是复制值。它应该排空c&#39; x并执行cout确认但没有发生这种情况。任何人都可以澄清我的代码发生了什么吗?

2 个答案:

答案 0 :(得分:2)

您的代码中没有发生任何动作。 func将引用作为参数,因此传递std::move(c)只会绑定引用 - 不会发生复制或移动。关键的事实是std::move不移动,它只返回指定对象的右值。如果您按值获取参数:

void func(carl get);

然后你将创建一个使用移动构造函数初始化的新对象(假设你将rvalue传递给func)。

答案 1 :(得分:2)

对于你的例子,这里,

void funct(carl&& get) { std::cout<<get.x<<std::endl; }

提供与

完全相同的行为
void funct(carl& get) { std::cout<<get.x<<std::endl; }

即:您传递对函数的引用。

只有当你将rvalue引用移动到新对象时,事情才会改变:

void funct(carl&& get)
{   
    auto my_carl = std::move(get); 
    std::cout<<my_carl.x<<std::endl;
}

然后编译器调用carl的移动构造函数将内容移出对象而不是复制。