Monday, July 17, 2017

C++11: Rvalue References: Move Constructors

There are two Move Contructors: MyClass(MyClass &&) and MyClass(const MyClass &&). Here is an example:

#include 
struct MyClass
{
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}

};

int main()
{
    MyClass          myNonConstObject; // Default CTOR called
    MyClass const    myConstObject;    // Default CTOR called
    MyClass       && myRefToNonConstObject(
                       []{MyClass nco; // Default CTOR called
                           return nco; 
                         }()); // Move CTOR called
    MyClass const && myRefToConstObject   (
                       []{MyClass const co; // Default CTOR called
                           return co;
                         }()); // Move CTOR2 called
    return 0;
}
 Output:
Default CTOR called
Default CTOR called
Default CTOR called
Move CTOR called
Default CTOR called
Move CTOR2 called
--
The following changes to the code and the result of the change.
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}

Compiles
Output:
Default CTOR called
Default CTOR called
Default CTOR called
Move CTOR2 called
Default CTOR called
Move CTOR2 called
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
Does not compile.
Error: attempting to reference a deleted function
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
Compiles.
Output:
Default CTOR called
Default CTOR called
Default CTOR called
Default CTOR called
--
  //MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
Does not compile.
Error: no appropriate default constructor available.
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}
Compiles
Output:
Default CTOR called
Default CTOR called
Default CTOR called
Copy CTOR called
Default CTOR called
Copy CTOR2 called
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}
Compiles
Ouput:
Default CTOR called
Default CTOR called
Default CTOR called
Copy CTOR2 called
Default CTOR called
Copy CTOR2 called
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  //MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}

Does not compile
Error: attempting to reference a deleted function
--
  //MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  //MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}
Compiles:
Output: None
Reference: https://isocpp.org/wiki/faq/cpp11-language#rval
http://en.cppreference.com/w/cpp/utility/move

No comments:

Post a Comment