![](/img/trans.png)
[英]What's the difference between std::ranges::swap() and std::swap()?
[英]How do I make std::sort not have name collision between std::swap and my namespace's templated 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());
}
};
一種解決方法是創建更好的重載:
// 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個有效的重載之間,所有的重載都是完全匹配的,但首選非模板。
與某些評論相反,有些令人驚訝的是,在不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
是更好的候選者(自定義swap
函數假定)的情況下,該調用才有效。
如Jarod42所示,解決方案是定義更好的候選swap
函數。
您可能正在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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.