Topic: Initialization in functional notation type conversion
Author: Janusz Szpilewski <janusz.szpilewski@vz.cit.alcatel.fr>
Date: 2000/04/04 Raw View
Homer Meyer wrote:
>
>
>
> You missed the very next sentence which is relevant. (btw, this is
from
> 12.2 paragraph 1)
>
> "Even when the creation of the temporary is avoided (12.8), all the
> semantic
> restrictions must be respected as if the temporary object was created.
> [Example: even if the copy constructor is not called all the semantic
> restrictions, such as accessibility (clause 11), shall be satisfied.]"
>
Well, strange. Especially when having in mind some excepts from the
Stroustoup's book mentioned before. I thought that direct-initialization
escaped from the case of "some initializations". But after some compiler
tests with g++ 2.95 it seems that it has to follow those rules. Of
course, as far as we can trust compilers, but I haven't found as well a
direct statement inside the standard telling otherwise.
It imposes some limitations. If someone wants to write a template
function with a template type local variable initialized with the
default constructor:
template <class T> void func()
{
T x = T();
//...
}
he/she will not be able to instantiate such a function for a class with
hidden copy ctor even if such operation is not directly used.
Fortunately it is not so common case when we want a template function to
work both with basic types and those with hidden copy ctors and
initialize an variable of the template type with the default
constructor.
> >
> > T x = T(a); <==> T x(a);
>
> Going to the section on functional type conversions: (5.2.3 paragraph
1)
>
> "A simple-type-specifier followed by a parenthesized expression-list
> constructs a value of the specified type given the expression list.
If
> the
> expression list is a single expression, the type conversion expression
> is
> equivalent (in definedness, and if defined in meaning) to the
> corresponding
> cast expression. If the simple-type-specifier specifies a class type,
> the
> class type shall be complete. If the expression list specifies more
> than a
> single value, the type shall be a class with a suitably declared
> constructor, and the expression T(x1, x2, ...) is equivalent in effect
> to
> the declaration T t( x1, x2, ... ); for some invented temporary
variable
> t,
> with the result being the value of t as an rvalue."
>
> >I hope no one claims that T x(a); creates a temporary object.
>
> Well according to the above it could be interpreted that way.
>
Not quite, the paragraph above says that T(x1, x2, ...) creates an
object looking like T t( x1, x2, ... ) that can be used only as a
rvalue.
It says nothing about T t( x1, x2, ... ) when it is declared by a
programmer.
> <rest SNIPped>
>
> Looking at 8.5 paragraph 12:
>
> "The initialization that occurs in argument passing, function return,
> throwing an exception, handling an exception, and brace-enclosed
> initializer
> lists is called copy-initialization and is equivalent to the form T x
=
> a;"
>
> And 8.5 paragraph 14:
>
> "-- If the initialization is direct-initialization, or if it is
> copy-initialization where the cv-unqualified version of the source
type
> is
> the same class as, or a derived class of, the class of the
destination,
> constructors are considered. The applicable constructors are
> enumerated,
> and the best one is chosen through overload resolution. The
constructor
> so
> selected is called to initialize the object, with the initializer
> expression(s) as its argument(s). If no constructor applies, or the
> overload resolution is ambiguous, the initialization is ill-formed."
>
> >From these quotes and the ones that you presented, I am beginning to
> think
> that you may be right, so I have cross-posted this to
> comp.lang.c++.moderated and comp.std.c++ in the hopes that some of the
> language lawyers can clear this up for us.
>
I think that some help may be needed, but I do not suppose that the
subject: "Re: [OT]Re: More Questions.." (not mentioning some flame war
at the beginning) may attract serious language lawyers ;) So I have
adjusted the topic a bit.
Anyway I hope we are coming to the end.
> Is
>
> T x = T(x1,x2,...);
>
> equivalent to
>
> T x(x1,x2,...);
>
> or
>
> In the first case, is a temporary conceptionally created (compiler may
> optimize it away) and the value then copied via the copy constructor?
>
After considering all the presented quotes I think some conclusions can
be made:
An object initialization in functional type conversion must follow its
rules but the temporary object _must_ be optimized away (or even not
considered).
So the constructions above are almost equivalent but in the first case,
class T must posses public copy ctor.
>
> class A {
> int v;
> A( const A& ); // copy constructor is private and unimplemented
> public:
> A( int x ) : v(x) {}
> };
>
> int main() {
> A a = A(1); // illegal?
> A b = 2; // illegal?
> A c(3);
> }
>
> My compiler (VC++ 5.0) produces:
>
> - an error on "A a = A(1);" This the expected behaviour if a
temporary
> is
> created and the copy constructor is called.
>
> - no error on "A b = 2;" This was a surprise after the first error.
> Now,
> I'm really confused.
>
Of course
A b = 2; <==> A b = A(2); conversion by constructor [class.conv.ctor]
So if such an expression creates a physical temporary it is a non
standard behaviour, and if it succeeds if the copy ctor is private it is
non standard as well.
Greetings,
Janusz
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]