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

时间:2019-04-18 19:08:02

标签: c++ swap unordered-map unordered-set

某些东西弄乱了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>'的成员

2 个答案:

答案 0 :(得分:0)

您应该只使用std :: unordered_set,无需提升。 Boost不必不必使用std算法。专门检查here,“所有标准容器对其进行了专门化,只交换了几个内部指针而不是全部内部指针,从而使它们可以恒定的时间运行。”部分。

boost和std之间肯定有很多东西是交叉兼容的,但是如果您需要的所有工具都在同一个命名空间中,则只需使用该工具即可。

答案 1 :(得分:0)

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。尝试最小化stdboost的混合。


关于错误-这看起来像是MSVC标准库中的错误; std::swap<vector>实现并没有明确地局限于vector,这是错误的,因为只要明确指定了类型,它都会失败。

大致如下:

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>类型。