Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有无序集合和自定义类型的boost bimap_C++_Boost - Fatal编程技术网

C++ 具有无序集合和自定义类型的boost bimap

C++ 具有无序集合和自定义类型的boost bimap,c++,boost,C++,Boost,我想使用bimap在自定义类之间创建一个双向映射,这就是我要做的(类a和类B是简化的,它们不仅仅存储整数): B类与A类相同,然后我创建了地图: typedef bimap< unordered_set_of<A, AHash, AComp>, unordered_set_of<B, BHash, BComp> > CustomMap; CustomMap my_map; typedef bimap< 无序的, 无序集 >海关地图;

我想使用bimap在自定义类之间创建一个双向映射,这就是我要做的(类a和类B是简化的,它们不仅仅存储整数):

B类与A类相同,然后我创建了地图:

typedef bimap< 
   unordered_set_of<A, AHash, AComp>,
   unordered_set_of<B, BHash, BComp> 
   > CustomMap;

CustomMap my_map; 
typedef bimap<
无序的,
无序集
>海关地图;
自定义地图我的地图;
它进行编译,但在没有有意义的日志的情况下崩溃

有关于我做错了什么的线索吗

顺便说一句:我使用的是c++03,我怀疑你有(例如内存管理,或者实际类型
A
B
)。下面是我自己的独立测试,它基于您的样本,包含大量随机插入和查找:

#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <iostream>

#include <boost/random.hpp> // for test
#include <boost/range/empty.hpp>
#include <boost/range/iterator_range.hpp>

template <typename>
class Obj
{
  private:
    int value1;
    int value2;
    boost::tuple<int const&, int const&> key() const { return boost::tie(value1, value2); }
  public:
    int get_value1() const { return this->value1;}
    int get_value2() const { return this->value2;}
    Obj(int value1, int value2): value1(value1), value2(value2) {};

    struct Hash {
        size_t operator()(const Obj& a) const {
            size_t seed = 0;
            boost::hash_combine(seed, a.get_value1());
            boost::hash_combine(seed, a.get_value2());
            return seed;
        }
    };

    struct Equality {
        bool operator()(const Obj& lhs, const Obj& rhs) const {
            return lhs.key() == rhs.key(); 
        }
    };
};

typedef Obj<struct TagA> A;
typedef Obj<struct TagB> B;

int myrandom() {
    static boost::mt19937 prng(42);
    static boost::uniform_int<> dist(0, 1000);
    return dist(prng);
}

int main() {

    typedef boost::bimaps::bimap< 
            boost::bimaps::unordered_set_of<A, A::Hash, A::Equality>,
            boost::bimaps::unordered_set_of<B, B::Hash, B::Equality> 
        > CustomMap;

    CustomMap map;

    int dupes = 0;
    for (int i=0; i < 10000; ++i)
    {
        A a(myrandom(), myrandom());
        B b(myrandom(), myrandom());

        if (!map.insert(CustomMap::value_type(a, b)).second)
            ++dupes;
    }

    std::cout << dupes << " duplicate insertions were skipped\n";

    int left_hits = 0;
    for (int i=0; i <= 10000; ++i)
        if (!boost::empty(boost::make_iterator_range(map.left.equal_range(A(i,i)))))
            ++left_hits;

    int right_hits = 0;
    for (int i=0; i <= 10000; ++i)
        if (!boost::empty(boost::make_iterator_range(map.right.equal_range(B(i,i)))))
            ++right_hits;

    std::cout << "Random hits (left, right): (" << left_hits << ", " << right_hits << ")\n";
}

即使在优化版本中,它也能在valgrind下正常运行。

您能公布哪一行崩溃了,以及无意义的日志是什么吗?@dlavila Mmm。所以我浪费了我的时间。我可以看到这种情况发生。我想如果我的答案对你有帮助,你仍然可以接受它(即使你同时发现了相同的解决方案),你的解决方案对我有帮助,这将是一个很好的例子,不是因为原始答案,而是我在SO中可以找到的一对一的自定义类bimap的最好的完整例子。这是我的第一个问题,所以我没有足够的声誉给你的答案排名,不过,我会在达到门槛后再做。我道歉。
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <iostream>

#include <boost/random.hpp> // for test
#include <boost/range/empty.hpp>
#include <boost/range/iterator_range.hpp>

template <typename>
class Obj
{
  private:
    int value1;
    int value2;
    boost::tuple<int const&, int const&> key() const { return boost::tie(value1, value2); }
  public:
    int get_value1() const { return this->value1;}
    int get_value2() const { return this->value2;}
    Obj(int value1, int value2): value1(value1), value2(value2) {};

    struct Hash {
        size_t operator()(const Obj& a) const {
            size_t seed = 0;
            boost::hash_combine(seed, a.get_value1());
            boost::hash_combine(seed, a.get_value2());
            return seed;
        }
    };

    struct Equality {
        bool operator()(const Obj& lhs, const Obj& rhs) const {
            return lhs.key() == rhs.key(); 
        }
    };
};

typedef Obj<struct TagA> A;
typedef Obj<struct TagB> B;

int myrandom() {
    static boost::mt19937 prng(42);
    static boost::uniform_int<> dist(0, 1000);
    return dist(prng);
}

int main() {

    typedef boost::bimaps::bimap< 
            boost::bimaps::unordered_set_of<A, A::Hash, A::Equality>,
            boost::bimaps::unordered_set_of<B, B::Hash, B::Equality> 
        > CustomMap;

    CustomMap map;

    int dupes = 0;
    for (int i=0; i < 10000; ++i)
    {
        A a(myrandom(), myrandom());
        B b(myrandom(), myrandom());

        if (!map.insert(CustomMap::value_type(a, b)).second)
            ++dupes;
    }

    std::cout << dupes << " duplicate insertions were skipped\n";

    int left_hits = 0;
    for (int i=0; i <= 10000; ++i)
        if (!boost::empty(boost::make_iterator_range(map.left.equal_range(A(i,i)))))
            ++left_hits;

    int right_hits = 0;
    for (int i=0; i <= 10000; ++i)
        if (!boost::empty(boost::make_iterator_range(map.right.equal_range(B(i,i)))))
            ++right_hits;

    std::cout << "Random hits (left, right): (" << left_hits << ", " << right_hits << ")\n";
}
112 duplicate insertions were skipped
Random hits (left, right): (11, 7)