I played around with explicit constructors and their behavior, so I created this class:
#include <iostream>
class X
{
public:
explicit X(void)
{
std::cout << "Default constructor\n";
}
explicit X(X const& x)
{
std::cout << "Copy constructor\n";
}
explicit X(X&& x)
{
std::cout << "Move constructor\n";
}
};
Which is basically just a stub to to test explicit constructors. Then I wanted to try several situations. So I tried this:
X foo(void)
{
X a{};
return a; // ERROR: no matching constructor found!
}
int main()
{
X w{}; // Default Constructor
X x{w}; // Copy Constructor
X y{std::move(x)}; // Move Constructor
X z{foo()};
}
And as you can see I can't return a
inside foo()
. I know it tries to initialize the return type Foo
with the copy constructor, but for some reason it can't use it.
How come it can't use my provided copy constructor? I know that the explicit
specification causes the problem, because when I remove it from the copy constructor it works. But why?
What confuses me even more is that I can do the following:
void bar(const X& a) { /* */ }
bar(X{});
It doesn't complain. But shouldn't bar()
construct it's parameter a
the same way foo()
constructs its return type?
When you are returning from foo
:
X foo()
{
X a{};
return a;
}
You are implicitly copying a
into the return of foo
. But the copy constructor is marked explicit
, so that is disallowed.
I'm not sure there is ever a reason to mark the copy/move constructors explicit
.
I think you've misunderstood the meaning of explicit
. An explicit
constructor WILL NOT BE USED FOR IMPLICIT TYPE CONVERSIONS/CASTS. This means the
X foo(void){
X a{};
return a; // ERROR: no matching constructor found!
}
won't compile since you've already told the compiler not to use the copy constructor implicitly.
I reckon that what you want to achieve is "move" rather than copy a
. As long as there is a (normal) move constructor in your class, a
will be moved rather than copied anyway - this is the default behaviour. Actually, even with c++99, most compilers are clever enough to optimise out this copy anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With