Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2005-12-19 14:28:40


Thorsten Ottosen wrote:
> Eric Niebler wrote:
>
>>I noticed this too, and decided it was a bug in gcc. I think that given
>>
>> template<typename T> struct conv {
>> operator T() { return T(); }
>> };
>> template<typename T> void bar(T&) {}
>>
>>the expression:
>>
>> typedef foo const cfoo;
>> bar(true ? conv<foo>() : cfoo());
>>
>>should compile,
>
>
> Even though bar takes a T& and not const T& parameter?

Yes. The type of (true ? conv<foo>() : cfoo()) is "rvalue of foo const."
And const rvalues successfully bind to T&, with T deduced as "foo const."

> It seems to me that conversion operators are a poorly understood part of
> the language. Maybe you should take this up on the reflector.

Just because you and I don't understand this completely doesn't mean
it's poorly understood by everyone. :-)

>
> Another thing I find wierd is that this seems to lead to ambiguity:
>
> template< class T >
> struct probe
> {
> operator T&();
> operator T();
> };
>
>
> int main()
> {
> int i = probe<int>(); // error
> int& r = probe<int>(); // ok
> }
>
> If I add const to the T() conversion, it suddenly works ok again.

Yes, that's because for the first line, there are two ways for the
conversion to succeed. It could call operator T(), or it could call
operator T&() followed by the standard lvalue-to-rvalue conversion.
Overload resolution is needed to choose between them, and without the
const qualification, neither is preferred. With the const, an extra
standard non-const-to-const conversion is needed before operator
T&()const can be invoked, which makes that conversion sequence longer
and less preferred.

HTH,

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk