0

What constructor is called when initialising with temporary object?

#include<iostream>
class Test{
    public:
    int a;
    Test(){
        std::cout<<"default"<<std::endl;
    }
    Test(Test& t):a(t.a){
        std::cout<<"copy constructor called"<<std::endl;
    }
    Test(int x):a(x){
        std::cout<<"int construct"<<std::endl;
    }
    Test(Test&& t):a(t.a){
        std::cout<<"rvalue reference"<<std::endl;
    }
    Test operator+(const Test& t1){
        Test out;
        out.a = a + t1.a;
        std::cout<<"a"<<a<<std::endl;
        return out;
    }
};

int main(){
    Test t(10), t1(20), t2(30);
    Test out(t+t1+t2);
    Test o(std::move(t));
}

Output:

int construct //from t(10)
int construct // from t1(20)
int construct // from t2(30)
default  // from inside operator+ 1st time
a10      // value of a from t
default // from inside operator+ 2nd time
a30     // value of a from temporary object
rvalue  // from Test(Test&& t)

How is out intialized here in Test out(t+t1+t2);? What constructor is called when initialising with temporary object.

But when I comment out Test(Test&& t) and removed this line Test o(std::move(t)); it gives me error: Compiled with g++ -std=c++11 -o new new.cpp, g++ -std=c++14 -o new new.cpp

new.cpp: In function ‘int main()’:
new.cpp:28:18: error: cannot bind non-const lvalue reference of type ‘Test&’ to an rvalue of type ‘Test’
new.cpp:9:16: note:   initializing argument 1 of ‘Test::Test(Test&)’

But when compiled with -std=c++17 no error is raised

int construct
int construct
int construct
default
a10
default
a30
TheScore
  • 329
  • 3
  • 14
  • Is there a question? – Joseph Larson Dec 03 '20 at 17:38
  • 1
    Your copy constructor should have a `const` reference parameter. Otherwise, it cannot accept rvalue arguments. Anyway, you may want to do some research about _copy elision_. – Daniel Langr Dec 03 '20 at 17:40
  • @JosephLarson *What constructor is called when initialising with temporary object?*, *How is out intialized here in Test out(t+t1+t2);? What constructor is called when initialising with temporary object.* – TheScore Dec 03 '20 at 17:41
  • @DanielLangr When I removed `Test(Test &&)` it raises error. When I uncomment it, it works fine. Can explain what happened there? – TheScore Dec 03 '20 at 17:43
  • @CPPnoob You're trying to force a move operation without a move constructor, so I'm not surprised the compiler complained. – Joseph Larson Dec 03 '20 at 17:44
  • @JosephLarson In C++17 is move construct added implicitely? – TheScore Dec 03 '20 at 17:47
  • That's deeper knowledge than I have. I don't know. It might fall back to the copy constructor. What does the output suggest? – Joseph Larson Dec 03 '20 at 17:48
  • @CPPnoob No, C++17 uses a different mechanism, so-called _deferred temporary materialization_. It does not require a corresponding copy/move constructor. While copy elision does. You may look here: [How does guaranteed copy elision work?](https://stackoverflow.com/questions/38043319/how-does-guaranteed-copy-elision-work) – Daniel Langr Dec 03 '20 at 17:49
  • Note that this question has been closed with 2 targets. You should read both of them, but if you feel your question is sufficiently different, and is not a duplicate, please ping me with @ , and I'll take a look. – cigien Dec 03 '20 at 17:54
  • 1
    @DanielLangr Thank you. I may not completely understand what's happening as of now but will refer to all the answers linked for better understanding in future. – TheScore Dec 03 '20 at 17:55
  • @cigien Thank you will go through both of them. – TheScore Dec 03 '20 at 17:57

0 Answers0