是什么东西搞乱了std :: swap和boost :: unordered_set?
我在使用std :: swap和boost :: unordered_set时遇到了一些问题。以下代码在VC2017 / VC2019上生成C2039错误。注释#include行,它可以很好地工作。有人对此问题有任何疑问吗?
#include <vector>
#include <boost/unordered/unordered_set.hpp>
typedef boost::unordered_set<size_t> index_list_type;
int main()
{
index_list_type toto;
index_list_type tutu;
std::swap<index_list_type>(toto, tutu);
return 0;
}
MSVC \ 14.20.27508 \ include \ vector(1702):错误C2039:'_ Alloc':不是'boost :: unordered :: unordered_set,std :: equal_to,std :: allocator>'的成员
你应该只使用std :: unordered_set,不需要提升。 Boost不必使用std算法。检查here特别是“所有标准容器专门化它,只交换几个内部指针而不是它们的全部内容,使它们在恒定的时间内运行。”部分。
当然,许多事情可能在boost和std之间交叉兼容,但是如果你需要的所有工具都在同一个命名空间中可用,那么就使用那个。
Boost本身就是一个完整的生态系统,旨在最大限度地减少对C ++标准库的依赖(请记住,std::swap
仅在C ++ 11之后可用)。因此,有boost::swap()
,它具有所有Boost数据类型的重载,包括boost::unordered_set
:
// swap
template<typename Value, typename Hash, typename Pred, typename Alloc>
void swap(unordered_set<Value, Hash, Pred, Alloc>&,
unordered_set<Value, Hash, Pred, Alloc>&);
如果你使用std::swap
然后你应该考虑std::unordered_set
,反之亦然,如果你不能或不想,那么你应该坚持使用Boost。尽量减少混合std
和boost
。
至于错误 - 这看起来像是MSVC标准库中的一个错误; std::swap<vector>
实现没有明确限制为vector
s,这是错误的,因为只要明确指定了类型,它就会失败。
看起来大致如下:
template<class T>
class _Vb_reference
{
using _Alvbase = typename T::_Alloc;
};
template<class T>
void swap(_Vb_reference<T> _Left, _Vb_reference<T> _Right)
{
}
这仅在推断出参数时才有效,如
std::swap(toto, tutu); // _Vb_reference<T> is non-deduced context
但是在明确指定类型时失败:
std::swap<index_list_type>(toto, tutu); // instantiation of _Vb_reference<index_list_type> fails = hard error
更好的实现将包括一些SFINAE将模板限制为_Vb_reference<T>
类型。