移动构造函数的预期用法没有发生

时间:2014-04-24 16:08:58

标签: c++ c++11

这是我的班级和我的课程:

class A {
    public:
        int x;
        int* v;
        A() : x(5), v(new int[5]) {cout<<"default ctor. "; for (int i=0; i<x; i++) v[i]=rand()%10;}
        A(const A& a) : x(a.x), v(new int[x]) {cout<<"copy ctor. "; for (int i=0; i<x; i++) v[i]=a.v[i]; }
        A(A&& a) : x(a.x), v(a.v) {cout<<"move ctor. ";a.x=0;a.v=0;}
        A& f() {return *this;}
        A g() {return *this;}
};

int main() {
    srand(time(0));
    cout<<"A a --> ";A a;cout<<endl;
    cout<<"A b(A()) --> ";A b(A());cout<<endl;
    cout<<"A c(a.f()) --> ";A c(a.f());cout<<endl;
    cout<<"A d(a.g()) --> ";A d(a.g());cout<<endl;
    cout<<"A e(A().g()) --> ";A e(A().g());cout<<endl;
}

我希望对象bde能够使用移动构造函数,但我得到的输出是:

  

A a - &gt;默认ctor。

     

A b(A()) - &gt;

     

A c(a.f()) - &gt;复制ctor。

     

A d(a.g()) - &gt;复制ctor。

     

A e(A()。g()) - &gt;默认ctor。复制ctor。

如果在所有三种情况下r值都是构造函数的参数,为什么不使用移动构造函数?

显然我正在使用-std=c++11选项进行编译。

1 个答案:

答案 0 :(得分:4)

使用b,您已点击“most vexing parse”。 b是一个函数声明,而不是一个对象。

采用表达式

A b(A());

让我们做一些名称更改和语义保留转换:

int foo(int (*p)());

现在,我认为很明显foo是一个函数(返回int并将int()函数指针作为参数)。现在将A替换为int,将b替换为foo并记住函数隐式转换为指向函数的指针。你会看到它是一样的。

为了解决这个问题,你可以使用大括号初始化(感谢@MikeSeymour指出这一点):

A b{A()};

使用d,我认为你是copy elision的“受害者”。 “copy ctor”输出可能是用*this初始化返回值;从返回值到d的移动完全被忽略了。

使用e,它与d的故事相同。

相关问题