Tente compilar o seguinte código.
#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;
}
Abaixo está o erro.
$ 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)
^~~~~~~~
Como você está usando operadores de conversão, há duas sequências de conversão definidas pelo usuário em jogo aqui (por meio do link de funções de conversão para padrões relevantes ). Nenhum deles tem classificação superior ao outro ( link para padrões relevantes ). A única maneira de desambiguar é realizar uma conversão para o tipo desejado:
std::string
sobrecarregouoperator=
s que aceitamchar
estd::string
como entrada eint
é implicitamente conversível emchar
. Seuv
objeto é conversível para ambos os tipos, portanto o compilador não sabe qualoperator=
sobrecarga chamar, daí a ambiguidade. Portanto, você deve informar explicitamente ao compilador para qual tipo deseja converter,v
para que ele saiba qualstring::operator=
usar.