Reputation:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&&c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test&z) {
printf(" test(const test&z)\n");
}
test& operator=( test&&e) {
printf(" test& operator=( test&&e)\n");
return *this;
}
};
int main()
{
test o ;
o = 4;
return 0;
}
The Output :
" test() "
" test(int y) "
" test& operator=( test&&e ) "
I thought that this line in the code o = 4 is creating an rvalue of object of the class ( test ) and passing it to the overloaded operator ( operator = )
But when i changed
test& operator=( test&&e )
into
test& operator=( test e )
and run the code again :
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
o = 4;
return 0;
}
The Output :
" test() "
" test(int y) "
" test& operator=( test e ) "
While I expected this Output after the change :
" test() "
" test(int y) "
" test(test&&c) noexcept "
" test& operator=( test e ) "
Because when i changed
test& operator=( test&&e )
into
test& operator=( test e )
the overloaded operator ( operator = ) now takes an object of the class test as parameter ( pass by value ) and the value that is passed to it is an rvalue so I expected that the constructor test(test&&c) noexcept
will be called
So why the constructor
test(test&&c) noexcept
is not called?
Explanation why I have this expectation:
because when you write this code and run it :
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
test x;
o = move(x); // this function ( move () ) returns an rvalue of its argument
return 0;
}
The Output :
" test() "
" test() "
" test(test&&c) noexcept "
" test& operator=( test e ) "
edit : this code
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
test x;
o = x;
return 0;
}
The Output :
" test() "
" test() "
" test(const test&z) "
" test& operator=( test e ) "
Upvotes: 1
Views: 256
Reputation: 1
So why the constructor
test(test&&c) noexcept
is not called?
This is due to non-mandatory copy elison prior to C++17.Under certain circumstances, the compilers are permitted, but not required to omit the copy and move (since C++11) construction of class objects.
You can verify this by providing the flag -fno-elide-constructors
in your 2nd example. And you'll get your expected output. Demo.
class test {
public:
test(int y) {
printf(" test(int y)\n");
}
test() {
printf(" test()\n");
}
test(test&& c) noexcept {
printf(" test(test&&c) noexcept\n");
}
test(const test& z) {
printf(" test(const test&z)\n");
}
test& operator=(test e) {
printf(" test& operator=( test e)\n");
return *this;
}
};
int main()
{
test o;
o = 4;
return 0;
}
Output with -fno-elide-constructors
flag:
test()
test(int y)
test(test&&c) noexcept
test& operator=( test e)
And if you don't provide this flag, then compilers are allowed to elide the copy/move construction in this situation and hence you were getting the output you mentioned.
Note that from C++17 onwards, the flag -fno-elide-constructors
won't have any effect on the output becasue of the mandatory copy elison.
Upvotes: 2