Topic: unwanted ambiguity with user-defined conversion and
Author: Martin Sebor <sebor@roguewave.com>
Date: Wed, 2 May 2001 03:52:17 GMT Raw View
Andrei Iltchenko wrote:
>
...
> > > I believe the standard requires the following assignment to be ambiguous
> > > (even though I expect that would surprise the user):
> > >
> > > double x;
> > > void f(const T& t) { x = t; }
> > >
> > > The problem is that both of these built-in operator=()s exist (13.6/18
> > > [over.built]):
> > > double& operator=(double&, int);
> > > double& operator=(double&, double);
> > >
> > > Both are an exact match on the first argument and a user conversion on
> the
> > > second. There is no rule that says one is a better match than the
> other.
...
> >
> > SCS UDC SCS
> > UCS1: T ==> T ==> int ==> double [Identity, UDC, Conversion]
> > UCS2: T ==> T ==> double ==> double [Identity, UDC, Identity]
> >
> > Wouldn't 13.3.3.1.2, p2 and 13.3.3, p1, bullet 6 cover this case?
> > I.e., user-defined conversion followed by an identity is a better
> > conversion sequence than a UDC followed by a conversion.
>
> No, they are not pertinent in this case. Because 'x = t' is not a
> declaration-statement but is an expression-statement.
> > double x;
> > void f(const T& t) { x = t; }
> I.e. 'x = t' is not an initialization of 'x' but is an assignment to it.
> 13.3.3, p1, bullet 6, which in turn refers to 13.3.1.5, speaks only about
> initialization. Your reasoning would've been correct had the example
> provided by Scott read:
> void f(const T& t) { double x = t; }
> but that is not the case.
Hmmm, I wonder then what 13.3.3.1.2, p2 means by
"Since an implicit conversion sequence is an initialization, the special rules
for initialization by user-defined conversion apply when selecting the best
user-defined conversion for a user-defined conversion sequence (see 13.3.3 and
13.3.3.1)."
>
> >From the set of candidate functions for the assignment expression 'x = t',
> which are all built-in candidates, the following two viable functions
> double& operator=(double&, int);
> double& operator=(double&, double);
> provide a better match than the rest of the viable functions like:
> double& operator=(double&, unsigned);
>
> However, none of the two functions provide a better match than the other,
> which renders the assignment ill-formed.
I have learned that that if most compilers (and thus their implementers)
don't consider something ill-formed, there's a good chance it isn't (or
it isn't intended to be, in which case Scott may have another issue to
write up :)
Martin
---
[ 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: scott douglass <sdouglass@arm.com>
Date: Wed, 2 May 2001 15:57:04 GMT Raw View
Martin Sebor wrote:
>
> Andrei Iltchenko wrote:
> >
> ...
> > >
> > > Wouldn't 13.3.3.1.2, p2 and 13.3.3, p1, bullet 6 cover this case?
> > > I.e., user-defined conversion followed by an identity is a better
> > > conversion sequence than a UDC followed by a conversion.
> >
> > No, they are not pertinent in this case. Because 'x = t' is not a
> > declaration-statement but is an expression-statement.
> > > double x;
> > > void f(const T& t) { x = t; }
> > I.e. 'x = t' is not an initialization of 'x' but is an assignment to it.
> > 13.3.3, p1, bullet 6, which in turn refers to 13.3.1.5, speaks only about
> > initialization. Your reasoning would've been correct had the example
> > provided by Scott read:
> > void f(const T& t) { double x = t; }
> > but that is not the case.
>
> Hmmm, I wonder then what 13.3.3.1.2, p2 means by
>
> "Since an implicit conversion sequence is an initialization, the special rules
> for initialization by user-defined conversion apply when selecting the best
> user-defined conversion for a user-defined conversion sequence (see 13.3.3 and
> 13.3.3.1)."
The above assignment 'x = t;' where 't' needs a user conversion is equivalent
to:
Y tmp(t);
x = tmp;
where Y is some type that 't' can be implcitly converted to (and 'tmp' is
actually a temporary). The quote above is saying that the implicit conversion
sequence (of 't' to 'Y') is an initialization (of the temporary).
> > However, none of the two functions provide a better match than the other,
> > which renders the assignment ill-formed.
>
> I have learned that that if most compilers (and thus their implementers)
> don't consider something ill-formed, there's a good chance it isn't (or
> it isn't intended to be, in which case Scott may have another issue to
> write up :)
I think I've given this thread enough time to be convinced that I haven't made a
simple mistake. I'll resend my original post as a defect report.
---
[ 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: Martin Sebor <sebor@roguewave.com>
Date: Sat, 28 Apr 2001 23:34:37 GMT Raw View
scott douglass wrote:
>
> Hello,
>
> This is closely related to core issue #260
> <http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_active.html#260> but is not
> resolved by the suggested resolution there.
>
> Given:
>
> struct T {
> operator int() const;
> operator double() const;
> };
>
> I believe the standard requires the following assignment to be ambiguous
> (even though I expect that would surprise the user):
>
> double x;
> void f(const T& t) { x = t; }
>
> The problem is that both of these built-in operator=()s exist (13.6/18
> [over.built]):
> double& operator=(double&, int);
> double& operator=(double&, double);
>
> Both are an exact match on the first argument and a user conversion on the
> second. There is no rule that says one is a better match than the other.
>
> The compilers that I have tried (even in their strictest setting) do not
> give a peep. I think they are not following the standard. They pick
> double& operator=(double&, double) and use T::operator double() const.
>
> Can you find a rule in the standard that makes one a better match than the
> other?
SCS UDC SCS
UCS1: T ==> T ==> int ==> double [Identity, UDC, Conversion]
UCS2: T ==> T ==> double ==> double [Identity, UDC, Identity]
Wouldn't 13.3.3.1.2, p2 and 13.3.3, p1, bullet 6 cover this case?
I.e., user-defined conversion followed by an identity is a better
conversion sequence than a UDC followed by a conversion.
Regards
Martin
---
[ 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 ]