* James Kanze:
Formally, it's copy initialization. But the standard also says
that if the type of the initialization is the same as, or a
class derived from, the target type, copy initialization behaves
the same as direct initialization. There is only a difference
when conversions are involved.
Exactly what I just said.
I don't think so, but the original standard is far from clear.
In the section on initialization, it makes it very clear that if
the initialization expression in copy initialization has the
same type as, or a type derived from, the target type, the
semantics are the same as those of direct initialization. In
the section concerning explicit, on the other hand, the latest
draft says that an explicit constructor will only be used "where
the direct-initialization syntax (8.5) or where casts (5.2.9,
5.4) are explicitly used."
This is also the language of the original standard.
It's not a contradiction: "explicit" is a limitation on allowable syntax
for constructor calls, namely that they must be explicit, and is not
concerned with the final semantic effect of a call.
In other words, §8.5 on initialization refers to the semantic effect,
whereas §12.3.1 on explicit constructors refers to which syntax syntax
is allowed.
Only in the cases where explicit constructor call syntax is not
available (the only such case I know is passing an argument by value)
does that limit what can be done, the possible semantics.
> (Of course, it contradicts this for
explicit default constructors in the very next sentence. But
that doesn't affect the copy constructor.)
I'm not sure I understand what you mean here or really what you're
referring to. Possibly you're talking about the exception for default
constructors. If so then yes I agree the wording is not very clear.
But no matter.
The simplest solution is just to never declare the copy
constructor explicit. (Since explicit is designed to prevent
conversions, and the copy constructor doesn't "convert" anything
in the classical sense of the word, the logical decision would
have been for explicit to be ignored on the copy constructor.)
That would introduce another special case (in addition to the default
constructor), and this time on the argument type. Which would either be
inconsistent with effect of -- I'm assuming this is allowed --
template< class T >
explicit MyClass( T const & );
or make this templated non-copy constructor allow different call
/syntax/ dependending on the actual argument /type/.
It's messy. I think perhaps the decision to mix construction and
conversion in one common syntax was not optimal, because it places the
decision of whether you want implicit conversion in one central place,
namely in the class definition. Instead, that decision may conceivably
better be expressed at each place a conversion would put its result,
with no implicit conversion as default. However, I'm not sure. It's
difficult to say without experience with a language that does this.
Cheers, & hth.,
- Alf