Topic: unwanted ambiguity with user-defined conversion and built-in
Author: scott douglass <sdouglass@arm.com>
Date: Mon, 30 Apr 2001 10:36:29 GMT Raw View
Andrea Ferro wrote:
>
> "scott douglass" <sdouglass@arm.com> wrote in message
> news:4.3.2.7.2.20010427163120.02575d78@mail1...
> > 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.
>
> Personally I'm not sure that issue is right. If the interpretation there is
> correct then
>
> short s1,s2;
> s1=s2;
>
> should also try to use "short& operator=(short&, int);" and I think this is not
> the case. I think the "R is a promoted arithmetic type" wording is either
> misleading (if it means that the type is promoted tu cv unqualified version of
> L) or in conflict with 5.17 sub 3.
No, overload resolution doesn't apply here since neither operand is of class or
enum type (13.3.1.2/1 and the note in 13.6/1). Only 5.17/3 applies.
> The issue says:
>
> struct T {
> operator short() const;
> operator int() const;
> };
>
> short s;
>
> void f(const T& t) {
> s = t; // surprisingly calls T::operator int() const
> }
>
> I do not agree. It should not call "T::operator int() const" but "T::operator
> short() const" for the standard as is.
Can you explain you're reasoning? In particular: which built-in operator= do
you think the standard says is chosen?
> > 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):
>
> I believe not. I think it should work as expected.
>
> > 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);
>
> I think the first one does not exist.
Why do you think that? 13.6/18 says:
For every triple (L, VQ, R), where L is an arithmetic type, VQ is either
volatile or empty, and R is a promoted arithmetic type, there exist candidate
operator functions of the form
VQ L& operator=(VQ L&, R);
[...]
L = 'double' satisfies "L is an arithmetic type", and
R = 'int' satisfies "R is a promoted arithmetic type", or
R = 'double' satisfies "R is a promoted arithmetic type"
so I think that both of these exist
double& operator=(double&, int);
double& operator=(double&, double);
as well as 5 more (which are not interesting for the example given)
double& operator=(double&, unsigned);
double& operator=(double&, long);
double& operator=(double&, unsigned long);
double& operator=(double&, float);
double& operator=(double&, long double);
> > Can you find a rule in the standard that makes one a better match than the
> > other?
>
> 5.17 sub 3. Not a better match, a different interpretation of the promotion that
> the second operand should undergo.
But 5.17/3 only appiles after overload resolution has selected a built-in
operator and has determined what convertions should be appilied (5/3 &
13.3.1.2/7).
>
> --
>
> Andrea Ferro
>
> ---------
> Brainbench C++ Master. Scored higher than 97% of previous takers
> Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
Hmmm. Maybe I should know better than to argue...
---
[ 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: Fri, 27 Apr 2001 17:25:38 GMT Raw View
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?
Thanks.
---
[ 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 ]