user180574
user180574

Reputation: 6094

c++ compilation failure of ambiguity related to implicit conversion

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

Answers (2)

Remy Lebeau
Remy Lebeau

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

AndyG
AndyG

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

Related Questions