Search code examples
c++ambiguous-call

Why am I getting ambiguous call for the following functions?


Consider the following:

template <typename T>
class testString
{
public:

  typedef T* iterator;

  void insert(iterator aPos, size_t numChars, T aChar);
  testString<T>& insert(size_t aIndex, size_t numChars, T aChar);
};

template <typename T>
void testString<T>::insert( iterator aPos, size_t numChars, T aChar )
{

}

template <typename T>
testString<T>& testString<T>::insert( size_t aIndex, size_t numChars, T aChar )
{
  return *this;
}

int main()
{
  testString<char> c;
  c.insert(0, 10, 'a'); // ambiguous call
  c.insert(1, 10, 'a'); // compiles fine

  return 0;
}

Why am I getting an ambiguous call? Initially, I had a guess (because it is 0, it can be anything), but then I looked at std::string. I looked at the source, and these are the two functions:

void               insert ( iterator p, size_t n, char c );
string&            insert ( size_t pos1, size_t n, char c );

And I tried the same calls with std::string, and it works fine. Now I have no clue why 0 works with std::string and is immediately recognized as a size_t while in my implementation it is not (another guess was type traits, but there is no evidence of it in the source)?


Solution

  • Ah, one of those times when you're like "wouldn't it be better if in c++, 0 was not the same as null?"

    Anyway, your iterator type is typedef'd to T*, which is char*, and 0 is a fine value for a char*, hence the ambiguity (er, as K-ballo wrote). In std::string, the iterator type won't be a char*, it'll be something fancy like another (templatized) class...