Topic: Using declarations and conversion operators
Author: Jason Merrill <jason@cygnus.com>
Date: 1998/05/18 Raw View
>>>>> Alexandre Oliva <oliva@dcc.unicamp.br> writes:
> Doug Harrison <dHarrison@worldnet.att.net> writes:
>>>> 4 ... For conversion functions, the function is considered to be a
>>>> member of the class of the implicit object argument for the purpose of
>>>> defining the type of the implicit object parameter.
>>> Which means that, in this case, the implicit object argument is
>>> subject to a pointer conversion, instead of being an exact match.
>> Wouldn't it mean the opposite, that an inherited conversion operator
>> is always considered a member of the derived class for the purposes of
>> determining the implicit object parameter's type?
> I don't think so. AFAIK, the type of the implicit object argument is
> the type of `*this' inside the member function.
No. The implicit object argument is the temporary created by the
expression `B()'. The implicit object parameter is `*this'. 'argument' is
always used to refer to the value passed to a function, and 'parameter' for
the decl initialized from that argument.
>> struct A { operator bool() const { puts("A"); return true; } };
>> struct B : A { operator int() const { puts("B"); return 0; } };
>> bool x = B();
>> Compiled under VC5, the output is "A".
>> Compiled under egcs 1.02, the output is "B".
Based on the passage you quote, I believe VC5 is correct.
> Compiled under the latest snapshot of egcs, it still prints `B', but
> there are warning messages at compile-time:
> test.cc:13: warning: choosing `B::operator int() const' over `A::operator bool() const'
> test.cc:13: warning: for conversion from `B' to `bool'
> test.cc:13: warning: because conversion sequence for `this' argument is better
> I don't understand why the message is duplicated, but it indicates
> the call is ambiguous, but egcs accepts it as an extension, which is
> ok WRT the Standard, because it issues a diagnostic.
It's not ambiguous, it's not an extension, it's a warning about potentially
confusing behavior. I now realize that the correct behavior is not
confusing, so that warning can go away.
Jason
---
[ 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 ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/18 Raw View
Jason Merrill <jason@cygnus.com> writes:
>>>>>> Alexandre Oliva <oliva@dcc.unicamp.br> writes:
>> Doug Harrison <dHarrison@worldnet.att.net> writes:
>>>>> 4 ... For conversion functions, the function is considered to be a
>>>>> member of the class of the implicit object argument for the purpose of
>>>>> defining the type of the implicit object parameter.
>>> struct A { operator bool() const { puts("A"); return true; } };
>>> struct B : A { operator int() const { puts("B"); return 0; } };
>>> bool x = B();
>>> Compiled under VC5, the output is "A".
> Based on the passage you quote, I believe VC5 is correct.
I hate this, but I have to agree with you, M$ got this right...
Thanks for correcting me, I should be allowed to post to comp.std.c++
after being awake for more than 24 hours... :-)
>> test.cc:13: warning: choosing `B::operator int() const' over `A::operator bool() const'
>> test.cc:13: warning: for conversion from `B' to `bool'
>> test.cc:13: warning: because conversion sequence for `this' argument is better
> I now realize that the correct behavior is not confusing, so that
> warning can go away.
I remember I have tested another code snippet in the last few weeks
that would print this warning message too, and, at that time, the
message seemed quite reasonable. Too bad I can't remember what the
code was like :-( but, as far as my memory goes, it also involved
user-defined conversion functions. I believe it it had something to
do with overload resolution between a conversion function and a
constructor or such.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
[ 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 ]
Author: dHarrison@worldnet.att.net (Doug Harrison)
Date: 1998/05/13 Raw View
Anyone know if the following is legal?
struct A
{
operator bool() const;
};
struct B : private A
{
using A::operator bool;
};
bool x = B();
Seems pretty straightforward to me, but my compiler complains that the
B -> A conversion is inaccessible. It does not complain if I use a
normal member function instead of a conversion operator.
I found the following in the FDIS:
13.3.1 Candidate functions and argument lists [over.match.funcs]
4 ... For conversion functions, the function is considered to be a
member of the class of the implicit object argument for the purpose of
defining the type of the implicit object parameter. For
non-conversion functions introduced by a using-declaration into a
derived class, the function is considered to be a member of the
derived class for the purpose of defining the type of the
implicit object parameter.
Does this mean that conversion functions don't mix with using
declarations? On the other hand, 7.3.3/4 implies that non-member
template conversion functions can be used with using declarations.
What's the rationale for distinguishing between conversion and
non-conversion functions above? Wouldn't the class of the implicit
object argument be B in the example above?
--
Doug Harrison
dHarrison@worldnet.att.net
---
[ 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 ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/14 Raw View
Doug Harrison <dHarrison@worldnet.att.net> writes:
> Anyone know if the following is legal?
> struct A { operator bool() const; };
> struct B : private A { using A::operator bool; };
> bool x = B();
I'd say it is.
> 13.3.1 Candidate functions and argument lists [over.match.funcs]
> 4 ... For conversion functions, the function is considered to be a
> member of the class of the implicit object argument for the purpose of
> defining the type of the implicit object parameter.
Which means that, in this case, the implicit object argument is
subject to a pointer conversion, instead of being an exact match. I
assume this is just for the sake of overload resolution, which is
orthogonal to access control. After (and if) overload resolution
selects `A::operator bool()const' as the conversion function to be
used, access control takes place, and the call should be accepted,
because there is one path (the public declaration in B) that permits
the access.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
---
[ 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 ]
Author: dHarrison@worldnet.att.net (Doug Harrison)
Date: 1998/05/16 Raw View
On 14 May 98 04:36:10 GMT, Alexandre Oliva <oliva@dcc.unicamp.br>
wrote:
>Doug Harrison <dHarrison@worldnet.att.net> writes:
>
>> Anyone know if the following is legal?
>
>> struct A { operator bool() const; };
>> struct B : private A { using A::operator bool; };
>> bool x = B();
>
>I'd say it is.
>
>> 13.3.1 Candidate functions and argument lists [over.match.funcs]
>
>> 4 ... For conversion functions, the function is considered to be a
>> member of the class of the implicit object argument for the purpose of
>> defining the type of the implicit object parameter.
>
>Which means that, in this case, the implicit object argument is
>subject to a pointer conversion, instead of being an exact match.
Wouldn't it mean the opposite, that an inherited conversion operator
is always considered a member of the derived class for the purposes of
determining the implicit object parameter's type? If not, then it
seems like there would be no need for any special language concerning
conversion operators.
Also, consider this example:
#include <stdio.h>
struct A
{
operator bool() const { puts("A"); return true; }
};
struct B : A
{
operator int() const { puts("B"); return 0; }
};
bool x = B();
int main() { return 0; }
Compiled under VC5, the output is "A".
Compiled under egcs 1.02, the output is "B".
If we consider both operators to have an implicit object parameter
type of B, then VC5 seems right. If we consider the implicit types to
reflect their respective classes, then I would say that neither
operator is a better match than the other, and I can't explain the
egcs result. What do you think?
(In any case, getting back to my original question, I agree, there
seems to be no reason why my original example involving a
using-declaration should be rejected.)
--
Doug Harrison
dHarrison@worldnet.att.net
---
[ 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 ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/16 Raw View
Doug Harrison <dHarrison@worldnet.att.net> writes:
>>> 4 ... For conversion functions, the function is considered to be a
>>> member of the class of the implicit object argument for the purpose of
>>> defining the type of the implicit object parameter.
>> Which means that, in this case, the implicit object argument is
>> subject to a pointer conversion, instead of being an exact match.
> Wouldn't it mean the opposite, that an inherited conversion operator
> is always considered a member of the derived class for the purposes of
> determining the implicit object parameter's type?
I don't think so. AFAIK, the type of the implicit object argument is
the type of `*this' inside the member function.
> #include <stdio.h>
Ugh! :-)
> struct A { operator bool() const { puts("A"); return true; } };
> struct B : A { operator int() const { puts("B"); return 0; } };
> bool x = B();
> Compiled under VC5, the output is "A".
> Compiled under egcs 1.02, the output is "B".
Compiled under the latest snapshot of egcs, it still prints `B', but
there are warning messages at compile-time:
test.cc:13: warning: choosing `B::operator int() const' over `A::operator bool() const'
test.cc:13: warning: for conversion from `B' to `bool'
test.cc:13: warning: because conversion sequence for `this' argument is better
test.cc:13: warning: choosing `B::operator int() const' over `A::operator bool() const'
test.cc:13: warning: for conversion from `B' to `bool'
test.cc:13: warning: because conversion sequence for `this' argument is better
I don't understand why the message is duplicated, but it indicates
the call is ambiguous, but egcs accepts it as an extension, which is
ok WRT the Standard, because it issues a diagnostic.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
---
[ 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 ]