Re: Template conversion operator ambiguity?
On Jul 22, 12:01 am, Ian Collins <ian-n...@hotmail.com> wrote:
While "porting" some existing code to g++, I ran into
a problem with a generic value class that uses a template
conversion operator to return values. Here's a stripped down
version:
#include <string>
struct Value
{
Value() {}
template <typename T> operator T() { return T(); }
};
int main()
{
Value v;
int n(v);
std::string s(v);
}
My original compiler is happy with the string initialisation,
but g++ whinges about the conversion being ambiguous (edited
to cut the noise):
example.cc:15: error: call of overloaded 'basic_string(Value&)' is ambiguous
candidates are:
std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*,
const _Alloc&)
std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const
std::basic_string<_CharT, _Traits, _Alloc>&)
std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&)
But it will happily accept
std::string s = v;
So my question is, which compiler is correct?
I'd say g++. In the original code, the compiler is supposed to
convert v to something that can be used to call a constructor of
std::string: since there are several constructors which take
a single argument, the compiler can't choose between them, and
the call is ambiguous.
When you modify the definition to use copy initialization (with
the = sign), the semantics are: convert the expression to
std::string, then use the copy constructor. In this case,
there's only one conversion the std::string which doesn't
involve more than one user defined conversions, so there is no
ambiguity.
--
James Kanze