Garmekain
Garmekain

Reputation: 674

Rvalue constructor not being called?

I have this struct

struct A {
    A()             { cout << "Default\n"; }
    A(const A& a)   { cout << "Const lvalue\n"; }
    A(const A&& a)  { cout << "Const rvalue\n"; }
    A(A& a)         { cout << "Lvalue\n"; }
    A(A&& a)        { cout << "Rvalue\n"; }
};

which I'm using to understand rvalues/lvalues.

When doing

A a1;
A a2{ a1 };

const A a3;
A a4{ a3 };

It correctly outputs

> Default
> lvalue
> Default
> Const lvalue

The problem is that when I do something like

A a{ A() };

The output is Default. But isn't A() an rvalue there? Shouldn't A::A(A&&) or A::A(const A&&) have to be called? what is happening here?

Upvotes: 2

Views: 114

Answers (1)

TartanLlama
TartanLlama

Reputation: 65770

You are not seeing Rvalue printed because the compiler is eliding the move. This is allowed even if the constructor has side effects.

If you pass -fno-elide-constructors to GCC or Clang then you will see the output:

clang++ -std=c++14 -O2 -pedantic -fno-elide-constructors main.cpp && ./a.out
Default
Rvalue

clang++ -std=c++14 -O2 -pedantic main.cpp && ./a.out
Default

Upvotes: 4

Related Questions