The code
class ElisionTest
{
public:
int n;
// ElisionTest(ElisionTest& other): n(other.n) {cout<<"copy constructor"<<endl;}
ElisionTest(int n): n(n) {cout<<"constructor"<<endl;}
};
int main(int argc, char const *argv[])
{
ElisionTest et = 10;
}
prints "constructor"
and that's fine. Now, when I uncomment the copy constructor, I get a compile time error:
cpp_test.cpp: In function 'int main(int, const char**)':
cpp_test.cpp:140:19: error: no matching function for call to 'ElisionTest::ElisionTest(ElisionTest)'
cpp_test.cpp:140:19: note: candidates are:
cpp_test.cpp:135:2: note: ElisionTest::ElisionTest(int)
cpp_test.cpp:135:2: note: no known conversion for argument 1 from 'ElisionTest' to 'int'
cpp_test.cpp:134:2: note: ElisionTest::ElisionTest(ElisionTest&)
cpp_test.cpp:134:2: note: no known conversion for argument 1 from 'ElisionTest' to 'ElisionTest& {aka ElisionTest&}'
Which probably goes on to show that here the copy constructor will be called with a temporary ElisionTest(10)
. And since you can't have a non-const reference to a temporary, making the argument of the copy constructor a const&
should resolve the error.
But, if I modify the copy constructor to take const ElisionTest&
instead of ElisionTest&
, there's no error and the output is "constructor"
again. Why didn't it print "copy constructor"
?
ElisionTest(ElisionTest& other);
A constructor with that signature allows the initialization of an ElisionTest
instance through an lvalue. When you do this:
ElisionTest et = 10;
This will construct an instance of ElisionTest
from a temporary. Your code is equivalent to:
ElisionTest et = ElisionTest(10);
This will call your constructor that takes a non-const reference and initialize et
with that. But a non-const reference cannot be bound to a temporary. That's why we will need to add const
to your copy-constructor so that it can support both lvalues and rvalues:
ElisionTest(ElisionTest const& other);
// ^^^^^
The reason you are seeing no output is because of something called copy-elision . The compiler can omit the call to the copy/move constructor. In GCC, you can use -fno-elide-constructors
to turn off copy-elision.
It outputs "constructor"
because it needs to convert from 10
to ElisionTest
.
It didn't also print "copy constructor"
because it got optimized away (copy elision). That's the only possible optimization that is allowed to alter the observable behavior of a program.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.