[...]
I don't know what the problem with that. There is no doubt
that the constructor is called. The issue is whether or not
you believe that the programmer has written code that calls
it.
Not even. I don't think anyone would argue that the programmer
doesn't write code which calls the constructor. The only real
issue is what is meant by "explicit" when speaking of an
"explicit constructor call". If "explicit" is meant to say: the
programmer has written an expression which intentionally and
expressedly calls the constructor, and does nothing else, I'm
sure that even Alf would agree that C++ doesn't have this.
As Alf has pointed out, of course, the same thing can be said
for calling a function, since you can't write an expression
which calls a function without also evaluating it's arguments.
And although I don't really agree with Alf here, I think he
certainly has at least a partial point: the address of the raw
memory in which the object is to be constructed is in a very
real sense a necessary argument to a constructor (if for no
other reason than the this pointer must be allocated), and any
necessary memory allocation can certainly be considered part of
evaluating that argument; there is a very real sense in which
something like "MyClass()" and "functionReturningMyClass()" are
similar, with the first calling the constructor, and the second
the function. In the end, we're not arguing about what actually
takes place in any given expression (I think Alf and Rolf agree
about that), but about how to best describe it. And we're not
helped by the fact that the standard describes it as a type
conversion, since that's a perfectly horrible way to talk about
it, given that there is nothing to convert. My preference is to
speak of "explicitly creating a temporary object", because I
think that most clearly expresses what is happening, and the
intent when I write such an expression. But Alf is certainly
not alone in calling it "explicitly calling a constructor". And
while I definitely prefer "explicitly creating an obejct",
"explicitly calling a constructor" is still better that
"explicit type conversion (functional notation)". (IMHO, of
course).
FWIW: the problem with Alf's point of view, IMHO, is that when
people ask about explicitly calling the constructor, they're
usually asking about something similar to what Java calls
"explicit constructor invocations". In C++, this would be
citing the base class in the initialization list for base
classes, but the current version of C++ doesn't have any
equivalent for the "alternate constructor invocation" of Java.
(In the next version of the standard, it will be possible for a
constructor to delegate to another constructor of the object in
the initialization list.) I have no problems with Alf using
"explicitly calling the constructor" as he does, any more than I
have problems with Stroustrup doing it (and Alf's usage does
correspond to Stroustrup's). On the other hand, when someone
asks about how to explicitly call the constructor, and they are
obviously using the phrase as it is used in Java, then the
correct answer is "you can't explicitly call the constructor in
C++". Because the context has defined "explicitly call the
constructor" in a way different from that used by Alf (or
Stroustrup). And in the way the context has defined "explicitly
call the constructor", it doesn't exist in (current) C++.
Count me in the "you can't call constructors" crowd.
You can create objects, but the implementation calls the
constructors for you as necessary. Any syntax you think you
are writing that is a constructor call, is in fact, a cast or
temporary object creation.
The problem, as I'm sure Alf would point out, is that the
standard doesn't define a syntax "temporary object creation",
any more than it defines a syntax "explicit constructor call".
And the people who start these threads aren't asking how to do
an "explicit type conversion", since they don't have anything to
convert.
All things considered: if I could find the time, I'd write up a
proposal to change the name of section §5.2.3 to "Explicit
creation of a temporary object". (It's not necessarily as
simple as it sounds. Remember that given:
struct A {} ;
struct B { operator A() ; } ;
, the expression "A( someB )" invokes B:
perator A(). And not
directly the constructor of A. And that with:
typedef A* APtr ;
as well, "APtr( ptrToB )" is a reinterpret_cast.)