Topic: Overload resolution implied without specifying how the set of candidate functions is to be formed


Author: "Andrei Iltchenko" <iltchenko@yahoo.com>
Date: Wed, 30 May 2001 22:12:59 GMT
Raw View
J. Stephen Adamczyk <jsa@edg.com> wrote in message
news:GE5M7q.8Cs@edg.com...
> >> Another detail worth of note is that in the draft version of the
Standard
> >as
> >> of 2 December 1996 the second bullet read:
> >> - A temporary of type "cv1 T2" [sic] is created, and a copy constructor
is
> >> called to copy the entire rvalue object into the temporary...
> >>
> >> Does anyone know what the reason for changing "a copy constructor" to
"a
> >> constructor" was? The former version didn't imply overload resolution.
>
> This was changed because the constructor selected might be
> generated from a template, and such a constructor is never
> considered a "copy constructor" (see 12.8 paragraph 2), even
> if it has a signature like one.

Ok, but now that the set of candidate functions is not limited to only the
copy constructors of T2, there might be some unpleasant consequences.
Consider a rather contrived sample below:

int   * pi = ::new(std::nothrow) int;
const std::auto_ptr<int>   & ri = std::auto_ptr<int>(pi);

In this example the initialization of the temporary of type 'const
std::auto_ptr<int>' (to which 'ri' is meant to be subsequently bound)
doesn't fail, as it would had the approach with copy constructors been
retained, instead, a yet another temporary gets created as the well-known
sequence:
std::auto_ptr<int>::operator std::auto_ptr_ref<int>()
std::auto_ptr<int>(std::auto_ptr_ref<int>)
is called (assuming, of course, that the set of candidate functions is
formed as per 13.3.1.3). The second temporary is transient and gets
destroyed at the end of the initialization. I doubt that this is the way
that the committee wanted this kind of reference binding to go.

Besides, even if the approach not restricting the set of candidates to copy
constructors is retained, it is still not clear how the initialization of
the temporary (to which the reference is intended to be bound) is to be
performed -- using direct-initialization or copy-initialization. Another
place in the Standard that would benefit from a similar clarification is the
creating of an exception object delineated in 15.1

> Overload resolution is (or may be) required even if you limit the
> choices to copy constructors.  There can be multiple copy
> constructors, e.g., one for lvalues, one for volatile objects,
> and overload resolution is used to select among them.

Agree, that's slipped my mind. Thank you for having corrected me.


Regards,

Andrei Iltchenko.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Andrei Iltchenko" <iltchenko@yahoo.com>
Date: Tue, 29 May 2001 21:36:28 GMT
Raw View
There is a place in the Standard where overload resolution is implied but
the way that a set of candidate functions is to be formed is omitted. See
below.

According to the Standard, when initializing a reference to a non-volatile
const class type (cv1 T1) with an rvalue expression (cv2 T2) where cv1 T1 is
reference compatible with cv2 T2, the implementation shall proceed in one of
the following ways (except when initializing the implicit object parameter
of a copy constructor) 8.5.3/5 bullet 2:

- The reference is bound to the object represented by the rvalue (see 3.10)
or to a sub-object within that object.

- A temporary of type "cv1 T2" [sic] is created, and a constructor is called
to copy the entire rvalue object into the temporary...

While the first case is quite obvious, the second one is a bit unclear as it
says "a constructor is called to copy the entire rvalue object into the
temporary" without specifying how the temporary is created -- by
direct-initialization or by copy-initialization? As stated in DR 152, this
can make a difference when the copy constructor is declared as explicit. How
should the set of candidate functions be formed? The most appropriate guess
is that it shall proceed as per 13.3.1.3.

Another detail worth of note is that in the draft version of the Standard as
of 2 December 1996 the second bullet read:
- A temporary of type "cv1 T2" [sic] is created, and a copy constructor is
called to copy the entire rvalue object into the temporary...

Does anyone know what the reason for changing "a copy constructor" to "a
constructor" was? The former version didn't imply overload resolution.

Am I missing something?


Regards,

Andrei Iltchenko.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Andrei Iltchenko" <iltchenko@yahoo.com>
Date: Tue, 29 May 2001 23:49:53 GMT
Raw View
Andrei Iltchenko <iltchenko@yahoo.com> wrote in message
news:9f132n$1iig1$1@ID-62495.news.dfncis.de...
>
> - The reference is bound to the object represented by the rvalue (see
3.10)
> or to a sub-object within that object.
>
> - A temporary of type "cv1 T2" [sic] is created, and a constructor is
called
> to copy the entire rvalue object into the temporary...
>
> While the first case is quite obvious, the second one is a bit unclear as
it
> says "a constructor is called to copy the entire rvalue object into the
> temporary" without specifying how the temporary is created -- by
> direct-initialization or by copy-initialization? As stated in DR 152, this
> can make a difference when the copy constructor is declared as explicit.
How
> should the set of candidate functions be formed? The most appropriate
guess
> is that it shall proceed as per 13.3.1.3.
>
> Another detail worth of note is that in the draft version of the Standard
as
> of 2 December 1996 the second bullet read:
> - A temporary of type "cv1 T2" [sic] is created, and a copy constructor is
> called to copy the entire rvalue object into the temporary...
>
> Does anyone know what the reason for changing "a copy constructor" to "a
> constructor" was? The former version didn't imply overload resolution.

Another contradictory detail to this issue is that the new wording is
somewhat in conflict with the footnote #93 that says that when initializing
the implicit object parameter of a copy constructor an implementation must
eventually choose the first alternative (binding without copying) to avoid
infinite recursion. This seems to suggest that the a copy constructor is
used for initializing the temporary of type "cv1 T2".


Cheers,

Andrei.


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]