两个std :: map' s的值是彼此的迭代器?

时间:2016-07-12 09:58:24

标签: c++ dictionary incomplete-type

我需要两个std::map s,其价值指向彼此'出于性能原因的要素 这是为了在已经遍历另一个元素时允许恒定插入/移除元素。

在C ++中正确实现此功能的最快方法是什么?请注意,显而易见的方法不起作用,因为第二个映射的类型在其迭代器可以被声明为第一个映射的值的类型之前是不完整的。 Variants是我唯一的选择,还是有更好的解决方案?

2 个答案:

答案 0 :(得分:2)

你想要一种相互递归的类型,据我所知,不能用(前向)声明来实现。但C ++提供了另一种着名的CRTP:

#include <map>

template <typename T>
struct BidirMapHelper {
    struct ReverseElt {
        ReverseElt() {}
        ReverseElt(typename T::iterator p) : v(p) {}
        typename T::iterator v;
    };
    typedef std::map<int, ReverseElt> ReverseMap;
};

struct BidirMap: BidirMapHelper<BidirMap>
{
    struct DirectElt {
        DirectElt() {}
        DirectElt(ReverseMap::iterator p) : v(p) {}
        ReverseMap::iterator v;
    };
    typedef std::map<int, DirectElt> DirectMap;
    typedef DirectMap::iterator iterator;
};

typedef BidirMap::DirectMap DirectMap;
typedef BidirMap::ReverseMap ReverseMap;

int main () {
    DirectMap m1;
    ReverseMap m2;
    m1[0] = m2.end();
    m2[0] = m1.end();
    return 0;
}

这在Linux下用g ++和clang ++完全编译,但我必须承认,我不确定它是否依赖于标准库的实现特性,例如使用SCARY迭代器。

答案 1 :(得分:1)

这是一个更简单的解决方案,但是,不能保证为std::map的任意符合标准的实现进行编译。然而它用gcc 4.4.7(甚至不支持-std = c ++ 11)和gcc 5.x,gcc 6.1,clang 3.x和icc 13.0.1编译(有和没有-std = C ++ 11)。

#include <map>

struct It1;
struct It2;

typedef std::map<int, It2> Map1;
typedef std::map<int, It1> Map2;

struct It2 : Map2::iterator
{
    It2() {}
    It2(Map2::iterator it) : Map2::iterator(it) {}
};

struct It1 : Map1::iterator
{
    It1() {}
    It1(Map1::iterator it) : Map1::iterator(it) {}
};

int main()
{
    Map1 m1;
    Map2 m2;

    m1[0] = m2.end();
    m2[0] = m1.end();
    return 0;
}