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(...);