简体   繁体   English

std :: swap boost :: unordered_set和std :: vector之间不兼容?

[英]Incompatibility between std::swap boost::unordered_set and std::vector?

something in is messing out with std::swap and boost::unordered_set ? 是什么东西搞乱了std :: swap和boost :: unordered_set?

I am experiencing some problems while using std::swap and boost::unordered_set. 我在使用std :: swap和boost :: unordered_set时遇到了一些问题。 The following code generates a C2039 error on VC2017/VC2019. 以下代码在VC2017 / VC2019上生成C2039错误。 Comment the line #include and it works finely. 注释#include行,它可以很好地工作。 Does someone has any clue about this problem ? 有人对此问题有任何疑问吗?

#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): error C2039: '_Alloc' : is not member of 'boost::unordered::unordered_set,std::equal_to,std::allocator>' MSVC \\ 14.20.27508 \\ include \\ vector(1702):错误C2039:'_ Alloc':不是'boost :: unordered :: unordered_set,std :: equal_to,std :: allocator>'的成员

You should just use std::unordered_set, no need for boost. 你应该只使用std :: unordered_set,不需要提升。 Boost doesn't have to work with std algorithms. 升压没有性病的算法工作 Check here expecially the "all standard containers specialize it in such a way that only a few internal pointers are swapped instead of their entire contents, making them operate in constant time." 在这里查看特别是“所有标准容器都专门化它,只交换几个内部指针而不是它们的全部内容,使它们在恒定的时间内运行。” part. 部分。

Sure many things might be cross compatible between boost and std, but if all the tools you need are available in the same namespace, just use that one. 当然,许多事情可能在boost和std之间交叉兼容,但是如果你需要的所有工具都在同一个命名空间中可用,那么就使用那个。

Boost is an entire ecosystem in itself, aimed at minimizing the reliance on the C++ standard library (remember that std::swap is available since C++11 only). Boost本身就是一个完整的生态系统,旨在最大限度地减少对C ++标准库的依赖(请记住, std::swap仅在C ++ 11之后可用)。 As such, there is boost::swap() , which has overloads for all Boost data types, including boost::unordered_set : 因此,有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>&);

If you use std::swap then you should consider std::unordered_set , and vice versa if you can't or don't want to, then you should stick with Boost all the way. 如果你使用std::swap然后你应该考虑std::unordered_set ,反之亦然,如果你不能或不想,那么你应该坚持使用Boost。 Try to minimize mixing std and boost . 尽量减少混合stdboost


As to the error - this looks like is a bug in the MSVC standard library; 至于错误 - 这看起来像是MSVC标准库中的一个错误; the std::swap<vector> implementation is not explicitly restricted to vector s, which is wrong since it fails whenever the type is specified explicitly. std::swap<vector>实现没有明确限制为vector s,这是错误的,因为只要明确指定了类型,它就会失败。

It looks roughly like this: 看起来大致如下:

template<class T>
class _Vb_reference
{
    using _Alvbase = typename T::_Alloc;
};

template<class T>
void swap(_Vb_reference<T> _Left, _Vb_reference<T> _Right)
{
}

That only works when the arguments are deduced , as in 这仅在推断出参数时才有效,如

    std::swap(toto, tutu); // _Vb_reference<T> is non-deduced context

But fails when the type is specified explicitly: 但是在明确指定类型时失败:

    std::swap<index_list_type>(toto, tutu); // instantiation of _Vb_reference<index_list_type> fails = hard error

A better implementation would include some SFINAE to restrict the template to _Vb_reference<T> types. 更好的实现包括一些SFINAE将模板限制为_Vb_reference<T>类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM