Compiler error in VC++2010 (clean in 2008!), "ambiguous call to overloaded function"
I'm hitting a compile error in VS2010 with code that compiles cleanly in VS2008.
Here's my error, from the Output Window, with all of its verbosity:
...\elementimpl.h(49): error C2668: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string' : ambiguous call to overloaded function
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(700): could be 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax> &&)'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(590): or 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const _Elem *)'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
while trying to match the argument list '(CXStr)'
and here's the code in error, elementimpl.h(49):
std::string getAttributeValue(const char* attr) { return getAttribute(CXStr(attr)); }
getAttribute() returns a CXStr (an ADT), which obviously no std::string constructor accepts, so it needs to convert the CXStr to something suitable.
CXStr can be converted to either a std::string or a char*:
class CXStr
{
public:
...
CXStr(std::string);
CXStr(const char* ch);
开发者_运维问答
const CXStr& operator=(const char*);
const CXStr& operator=(std::string&);
operator char*();
operator std::string();
...
}
When I run through the debugger in VS2008, I can see that it goes through "CXStr::operator std::string()" after getAttribute(), and then it goes through the std::string copy constructor to create the object to be returned by getAttributeValue(). I want my 2010 build to behave the same way.
My questions:
- What is VS2010 doing differently, and why?
- What code change can I make to
fix this error? Some things that
work, but are unsatisfactory:
- commenting out "CXStr::operator char*()"; unsatisfactory because some other code uses this conversion.
- explicitly calling "getAttribute(...).operator std::string()" at elementimpl.h(49); unappealing because this same error occurs in 27 different places and it seems like there must be a more centralized way to fix it.
The problem is, that VS2010 added move constructors and your implementation falls directly into this hole.
Previously there was only one constructor, the const char* one, which was available to the std::string constructor. Now there is the move constructor, too.
I really think a design relying on implicit conversions is dangerous. Thats why all one parameter constructors should be explicit ...
I think you should discourage the use of implicit operators, because they lead to bad overloads being used. If you cannot do that, wrap the currently failing calls into an explicit conversion call std::string( CXStr( x ).toString() )
. There can be other errors which are hidden by using 'non-explicit' cast operators ... .
Why haven't you tried commenting out operator std::string() yet?
You could also explicitly cast your CXStr to std::string.
Frankly though, I can't see the use of this CXStr thing. What, if anything, does it provide in the way of services?
精彩评论