Reputation: 6094
Try to compile the following code.
#include <string>
#include <boost/any.hpp>
class V
{
public:
V& operator=(int i)
{
v = i;
return *this;
}
V& operator=(const std::string& s)
{
v = s;
return *this;
}
operator int() const
{
return boost::any_cast<int>(v);
}
operator std::string() const
{
return boost::any_cast<std::string>(v);
}
private:
boost::any v;
};
int main()
{
V v;
std::string s1 = "hello", s2;
v = s1;
s2 = v;
}
Below is the error.
$ g++ test__boost_any.cpp
test__boost_any.cpp: In function ‘int main()’:
test__boost_any.cpp:37:9: error: ambiguous overload for ‘operator=’ (operand types are ‘std::__cxx11::string’ {aka ‘std::__cxx11::basic_string<char>’} and ‘V’)
s2 = v;
^
In file included from /usr/include/c++/8/string:52,
from test__boost_any.cpp:1:
/usr/include/c++/8/bits/basic_string.h:668:7: note: candidate: ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
operator=(const basic_string& __str)
^~~~~~~~
/usr/include/c++/8/bits/basic_string.h:718:7: note: candidate: ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
operator=(_CharT __c)
^~~~~~~~
/usr/include/c++/8/bits/basic_string.h:736:7: note: candidate: ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
operator=(basic_string&& __str)
^~~~~~~~
Upvotes: 2
Views: 112
Reputation: 598134
std::string
has overloaded operator=
s that accept char
and std::string
as input, and int
is implicitly convertible to char
. Your v
object is convertible to both types, so the compiler doesn't know which operator=
overload to call, hence the ambiguity. So you have to explicitly tell the compiler which type you want to convert v
to so it then knows which string::operator=
to use.
Upvotes: 2
Reputation: 41220
Since you are using conversion operators, there are two user defined conversion sequences at play here (via conversion functions link to relevant standardese). Neither is ranked higher than the other (link to relevant standardese). The only way to disambiguate is to perform a cast to the desired type:
s2 = static_cast<std::string>(v);
Upvotes: 4