I have a function in my namespace. Its name is destroy. std namespace also contains a function with this name. When I call my function within my namespace, the call is ambiguous, because std::destroy is also added to overload resolution set by argument dependent lookup.
#include <string>
#include <memory>
namespace my {
template <typename TIter>
void destroy(TIter it_begin, TIter it_end) noexcept
{
// Dummy
}
void func(std::string *p_begin, std::string *p_end)
{
destroy(p_begin, p_end);
}
}
The code above fails to compile.
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'void my::func(std::string*, std::string*)':
main.cpp:14:16: error: call of overloaded 'destroy(std::string*&, std::string*&)' is ambiguous
14 | destroy(p_begin, p_end);
| ~~~~~~~^~~~~~~~~~~~~~~~
main.cpp:7:10: note: candidate: 'void my::destroy(TIter, TIter) [with TIter = std::__cxx11::basic_string<char>*]'
7 | void destroy(TIter it_begin, TIter it_end) noexcept
| ^~~~~~~
/usr/local/include/c++/11.2.0/bits/stl_construct.h:240:5: note: candidate: 'void std::destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::__cxx11::basic_string<char>*]'
240 | destroy(_ForwardIterator __first, _ForwardIterator __last)
| ^~~~~~~
Ok, I can explicitly specify namespace when calling this function: my::destroy(p_begin, p_end). But that's not a generic solution. Imagine I add a function void ababaken(std::string) but later a function with the same name is added to std. My code will produce compilation error again. And I do not want to explicitly specify namespace for every function call.
What else can I do to avoid ambiguity with std namespace when std function is caught up by ADL? How can I prevent ADL?