Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do not C++11's move constructor/assignment operator act as expected

#include <iostream>

using namespace std;

struct A
{
    A()
    {
        cout << "A()" << endl;
    }

    ~A()
    {
        cout << "~A()" << endl;
    }

    A(A&&)
    {
        cout << "A(A&&)" << endl;
    }

    A& operator =(A&&)
    {
        cout << "A& operator =(A&&)" << endl;
        return *this;
    }
};

struct B
{
    // According to the C++11, the move ctor/assignment operator
    // should be implicitly declared and defined. The move ctor
    // /assignment operator should implicitly call class A's move
    // ctor/assignment operator to move member a.
    A a;
};

B f()
{
    B b;

    // The compiler knows b is a temporary object, so implicitly 
    // defined move ctor/assignment operator of class B should be
    // called here. Which will cause A's move ctor is called.
    return b; 
}

int main()
{
    f();
    return 0;
}

My expected output should be:

A()
A(A&&)
~A()
~A()

However, the actual output is: (The C++ compiler is: Visual Studio 2012)

A()
~A()
~A()

Is this a bug of VC++? or just my misunderstanding?

like image 775
xmllmx Avatar asked Sep 28 '12 21:09

xmllmx


2 Answers

According to this blog post, VC++ 2012 currently implements N2844 + DR1138, but not N3053. As a result, the compiler is not implicitly generating move constructors or assignment operators for you. If you add explicit default and move constructors to B then you will get the output you expect.

like image 133
ildjarn Avatar answered Nov 16 '22 00:11

ildjarn


Visual C++ 2012 does not implement the final C++11 specification for rvalue references and move operations (the specification changed several times during the standardization process). You can find out more information in the Visual C++ Team Blog post, "C++11 Features in Visual C++ 11", under rvalue references.

In your example specifically, this manifests itself in two ways:

  • the definition of the user-defined move operations in A do not suppress the implicitly-declared copy operations.

  • there are no implicitly defined move operations for B.

like image 27
James McNellis Avatar answered Nov 16 '22 02:11

James McNellis