Reputation: 674
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
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