0

I defined a class with both copy and move constructors. The copy constructor seems to work fine but when I try to invoke the move constructor it doesn't work.

#include <iostream>

class A{

        public:
                A() = default;

                A(A& a){
                        std::cout << "Copy constructor." << std::endl;
                };

                A(A&& a){
                        std::cout << "Move constructor." << std::endl;
                };
};


int main(int argc, char *argv[]){

        auto a = A(A());
        
        std::cout << "here" << std::endl;       

        auto b = A(a);

        return 0;
}

I expect the auto a = A(A()); should invoke move constructor because its input (A()) is an rvalue. But the output is this:

[amirreza@localhost tmp]$ ./a.out 
here
Copy constructor.

Is my assumption wrong?

I'm using gcc version 10.3.1 without explicitly specifying the c++ version.

Amir reza Riahi
  • 1,540
  • 2
  • 8
  • 34
  • The copy constructor should take a `const` reference, I would say. Which line produces the output you quoted? – Ulrich Eckhardt Jul 22 '22 at 15:26
  • 4
    Your assumption is wrong. `auto a = A(A());` is allowed to simply call the default constructor, and since C++17 it is required that the move be elided. – Drew Dormann Jul 22 '22 at 15:27
  • @UlrichEckhardt I think this `auto b = A(a);` – Amir reza Riahi Jul 22 '22 at 15:28
  • @DrewDormann would you give more info? or link to read more? – Amir reza Riahi Jul 22 '22 at 15:29
  • 2
    https://en.cppreference.com/w/cpp/language/copy_elision – fabian Jul 22 '22 at 15:29
  • 1
    Can you find out which line causes it and [edit] your question to clarify? Also, which C++ version are you targetting? – Ulrich Eckhardt Jul 22 '22 at 15:30
  • @UlrichEckhardt It's safe to assume that `A(a)` is the source of the call to the constructor taking an lvalue reference... – fabian Jul 22 '22 at 15:33
  • Because the language has constraints and requirements for constructor semantics, **copy elision** can happen which will cause *side-effects* (like `std::cout`) to not occur. This has been part of C++ for a very long time (as a possible compiler optimization), and as of C++17 is *required* behavior. – Eljay Jul 22 '22 at 15:34
  • Standard reference: https://eel.is/c++draft/dcl.init.general#16.6.1 – jcai Jul 22 '22 at 15:35

0 Answers0