Home > Back-end >  ambiguous call to function template (reverse)
ambiguous call to function template (reverse)

Time:01-30

This code compiles with GCC, but gives ambiguous call to overloaded function for MSVC: https://godbolt.org/z/W89xn15d3

#include <string>

template <typename Iter>
void reverse(Iter begin, Iter end){
  if (std::distance(begin, end) == 0)
    return;
  
  auto left = begin,
    right = std::prev(end);

  while (left < right)
    std::swap(*left  , *right--);
}

std::string reverseWordsInString(std::string str) {
  reverse(str.begin(), str.end()); // ambiguous call
//   reverse(str.data(), str.data()   str.size());

  size_t wordLength = 0;
  for (size_t i = 0; i < str.size();   i)
  {
    if (str[i] != ' ')
    {
        wordLength;
      continue;
    }
    
    const size_t offset = i - wordLength;
    reverse(str.data()   offset, str.data()   i);
    wordLength = 0;
  }

  // reverse(std::prev(str.end(), wordLength), str.end()); // ambiguous
  reverse(str.data()   str.size() - wordLength, str.data()   str.size());

  return str;
}

MSVC output:

example.cpp
<source>(16): error C2668: 'reverse': ambiguous call to overloaded function
<source>(4): note: could be 'void reverse<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>>(Iter,Iter)'
        with
        [
            _Elem=char,
            Iter=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
        ]
C:/data/msvc/14.33.31631/include\xutility(5619): note: or       'void std::reverse<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>>(const _BidIt,const _BidIt)' [found using argument-dependent lookup]
        with
        [
            _Elem=char,
            _BidIt=std::_String_iterator<std::_String_val<std::_Simple_types<char>>>
        ]
<source>(16): note: while trying to match the argument list '(std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>, std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>)'
        with
        [
            _Elem=char
        ]
Compiler returned: 2

Who is wrong and why?

CodePudding user response:

You'll get the same error in GCC if you #include <algorithm>. MSVC is including <algorithm> implicitly when you #include <string>.

The portable solution is to either:

  • rename your function to something that doesn't exist in the standard library

  • be explicit about the namespace when you want to call your function:

    ::reverse(...);
    
  • place your function in a namespace of your own, and then prepend the call with that namespace.

    myns::reverse(...);
    
  • Related