Вопреки некоторым комментариям и удивительным для некоторых эта ошибка происходит без using namespace std
.Вот минимальный пример, чтобы понять, что происходит:
namespace like_std
{
template<class T> void swap(T a, T b) {}
template <class T> auto test(T x, T y)
{
swap(x, y); // (1) ambiguous call
}
}
namespace my
{
template<class T> void swap(T a, T b) {}
struct Obj {};
void doStuff()
{
like_std::test(Obj{}, Obj{});
}
};
Вы вызываете функцию из like_std
, и внутри этой функции есть безусловный вызов swap
.Для этого вызова:
like_std::swap
является кандидатом, поскольку находится в том же пространстве имен, что и вызов swap
my::swap
является кандидатом из-за ADL: он введен, потому что он находится в том же пространстве имен, что и один из аргументов для вызова swap
Поскольку ни один из них не является лучшим, возникает двусмысленность.
Причина, по которой вызов swap
является неквалифицированным, заключается в том, что он выберет пользовательский swap
, если он определен, , но , который работает, только если пользовательский swap
является лучшим кандидатом, который предполагается для пользовательской функции swap
.
Решение, показанное Jarod42 , заключается в определении лучшего кандидата swap
функция.