
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