Topic: Defect Report: Direct class initialization via explicit


Author: Edward Catmur<ed@catmur.co.uk>
Date: Tue, 18 Sep 2012 08:24:46 -0700 (PDT)
Raw View
The resolution of issue 1087[1] was intended to permit the use of an explicit
conversion function in direct-initialization of a class type object via a copy-,
move- or template constructor.  Unfortunately, the language used is sufficiently
lax to permit the use of a converting constructor taking class type:

     struct X {};
     struct Y { Y(const X&); };    // converting constructor
     struct Z { explicit operator X() const; };
     void h(Z z) {
       Y y1(z);    // should not be permitted
     }

The converting constructor of Y is considered for direct-initialization
(13.3.1.3 [over.match.ctor]), and to initialize the temporary X to be bound to
the first parameter of the constructor (13.3.1.4 [over.match.copy]), the
explicit conversion function of Z is considered.  13.3.1.4 should be tightened
to not apply to converting constructors.

When discussing this issue[2], it became apparent that the definition of
conversion functions in 12.3.2 [class.conv.fct] does not make it clear that the
validity of explicit conversion functions in a direct-initialization expression
is governed by the semantics of overload resolution. A cross-reference to the
relevant sections would help here.

Suggested resolution:

1. Change 13.3.1.4 [over.match.copy] paragraph 1 second bullet as follows:

* When the type of the initializer expression is a class type "cv S", the non-
explicit conversion functions of S and its base classes are considered. When
initializing a temporary to be bound to the first parameter of a constructor
that takes a reference to possibly cv-quali   ed T as its first argument, called
with a single argument in the context of direct-initialization
<ins>
of an object of type "cv2 T"
</ins>,
explicit conversion functions are also considered. Those that are not hidden
within S and yield a type whose cv-unqualified version is the same type as T or
is a derived class thereof are candidate functions. Conversion functions that
return "reference to X" return lvalues or xvalues, depending on the type of
reference, of type X and are therefore considered to yield X for this process
of selecting candidate functions.

2. Change 12.3.2 [class.conv.fct] second paragraph as follows:

A conversion function may be explicit (7.1.2), in which case it is only
considered as a user-defined conversion for direct-initialization (8.5)
<ins>
as specified by the semantics of overload resolution (13.3.1.4, 13.3.1.5,
13.3.1.6)
</ins>.
Otherwise, user-defined conversions are not restricted to use in assignments
and initializations.

Credit and thanks are due to Jesse Good and Luc Danton for helping me understand
this issue.

Regards,

Ed Catmur

      [1]: http://www.comeaucomputing.com/iso/cwg_defects.html#1087
      [2]: http://stackoverflow.com/questions/12372442/explicit-conversion-functions-direct-initialization-and-converting-constructor


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?UTF-8?B?RGFuaWVsIEtyw7xnbGVy?= <daniel.kruegler@googlemail.com>
Date: Tue, 18 Sep 2012 13:06:30 -0700 (PDT)
Raw View
Am 18.09.2012 17:24, schrieb Edward Catmur:
>
> The resolution of issue 1087[1] was intended to permit the use of an explicit
> conversion function in direct-initialization of a class type object via a copy-,
> move- or template constructor.  Unfortunately, the language used is sufficiently
> lax to permit the use of a converting constructor taking class type:
>
>       struct X {};
>       struct Y { Y(const X&); };    // converting constructor
>       struct Z { explicit operator X() const; };
>       void h(Z z) {
>         Y y1(z);    // should not be permitted
>       }
>
> The converting constructor of Y is considered for direct-initialization
> (13.3.1.3 [over.match.ctor]), and to initialize the temporary X to be bound to
> the first parameter of the constructor (13.3.1.4 [over.match.copy]), the
> explicit conversion function of Z is considered.  13.3.1.4 should be tightened
> to not apply to converting constructors.
>
> When discussing this issue[2], it became apparent that the definition of
> conversion functions in 12.3.2 [class.conv.fct] does not make it clear that the
> validity of explicit conversion functions in a direct-initialization expression
> is governed by the semantics of overload resolution. A cross-reference to the
> relevant sections would help here.


I forwarded this to the core language working group.

Thanks & Greetings from Bremen,

Daniel Kr   gler



--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]