Как сделать так, чтобы в std :: sort не было конфликтов имен между std :: swap и шаблонным swap моего пространства имен?

Я хочу использовать std::sort, но компиляция не удалась с ошибкой C2668: std::swap: ambiguous call to overloaded function потому что есть шаблон swap() функция, определенная в моем пространстве имен, от которой было бы трудно избавиться. Мне все равно, какие swap он использует, но как заставить один из них уйти при компиляции sort()?

Я понимаю, что это неоднозначно, потому что my::swap находится в том же пространстве имен, что и my::Objи мне все равно какая версия swap привыкает. Я просто должен преодолеть столкновение пространства имен. Это часть очень большой базы кода, которой я не владею, поэтому я надеюсь на решение, которое является локальным для моего кода и, по-видимому, позволяет my::Obj а также my::swapчтобы оба оставались в пространстве имен my,

namespace my
{
template<class T> void swap(T a, T b)
{
}

struct Obj
{
};

void doSortStuff()
{
std::vector<Obj> arr;
std::sort(arr.begin(), arr.end());
}
};

0

Решение

Обходной путь должен создать лучшую перегрузку:

// No modifiable code
namespace my
{
template<class T> void swap(T a, T b) { /*.. */ }
struct Obj { /*..*/ };
}

// Your code:
namespace my
{
void swap(Obj& lhs, Obj& rhs)
{
// my::swap<Obj&>(lhs, rhs);
std::swap(lhs, rhs);
}
}

// In namespace you want.
void doSortStuff()
{
std::vector<my::Obj> arr;
std::sort(arr.begin(), arr.end());
}

Затем, между 3 допустимыми перегрузками, все точно совпадают, но не-Шаблон является предпочтительным.

2

Другие решения

Вопреки некоторым комментариям и удивительным для некоторых эта ошибка происходит без 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 функция.

1

Ты наверное using namespace std;,

В этом случае компилятор не знает, что выбрать, так как он делает все std:: элементы доступны без ввода автоматически, где подходят обе функции:

using namespace std;
swap(a, b); //your swap
swap(a, b); //std::swap

Как и в этом случае, у вас есть строгие вызовы функций:

std::swap(a, b); //from std
swap(a, b); // your one

На самом деле это очень хороший пример того, почему вы должны избегать using namespace std, Удачи!

Обновление: это может быть вашим решением — переместите swap() вне std::sort() использование:

#include <algorithm>
#include <vector>

namespace detail
{
struct someContainer
{
someContainer(int &v)
{
value = v;
}
int value;
someContainer &operator = (const someContainer & rhs)
{
this->value = rhs.value;
}
bool operator == (someContainer &rhs) const
{
return this->value == rhs.value;
}
bool operator <= (someContainer &rhs) const
{
return this->value <= rhs.value;
}
bool operator >= (someContainer &rhs) const
{
return this->value >= rhs.value;
}
bool operator > (someContainer &rhs) cosnt
{
return this->value > rhs.value;
}
bool operator < (someContainer &rhs) const
{
return this->value < rhs.value;
}
};
void doSomeStuff()
{
std::vector<someContainer> vec;
for (int i = 0; i < vec.size(); ++i)
{
vec.push_back(someContainer(i));
}
std::sort(vec.begin(), vec.end());
}
}

namespace mySwap
{
template< class T >
void swap(T &a, T &b)
{
T c = a;
a = b;
b = c;
}
}
int main()
{
detail::doSomeStuff();
return 0;
}
-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector