c – 表示意味着交叉引用的数据结构的STL方式

我经常遇到以下情况. (不失一般性:我在下面的示例中使用了两个容器的最简单的可能情况,但在几何算法的实现中,需要大量的描述互连图形数据结构.)

我有两个数据类型A和B的大量值,它们相互引用(一般不是一对一),比如说,首先是通过(本机)指针或引用引用的.使用CA = std :: container1

struct A;
struct B;

using CA = std::container1< A >;
using CB = std::container2< B >;

我想将A和B定义如下:

struct A
{
    int payload;
    typename CB::iterator pb; // hard error here in general case of choosing `std:container2`
};

struct B
{
    double payload;
    typename CA::iterator pa;
};

// ...
PA a;
PB b;
// ...
assert(!a.empty());
assert(a.begin()->pb != b.end()); // and pb is not default-constructed
b.erase(a.begin()->pb);

Live example.

但是目前我不能声明typename CB :: iterator pb;一般情况下,只有B / * const * / * pb;或B / * const * /& pb;,因为类型B是CB声明的一部分,在使用容器CB的成员typedef迭代器到聚合A的定义时是不完整的.

有一个不完整类型的容器的提议,但它目前不是标准的一部分.

对于libstdc和libc中当前实现的非调试版本的容器,上面的代码可能会被编译得很好,但它根本不是强制性的.如果成功,迭代器的定义除了指针或对value_type的引用之外不包含任何东西.但是标准中没有要求.

正如您在live example中看到的那样,std :: unordered_set存在硬错误,因为它的迭代器需要将value_type的std :: hash作为完整类型.

由于架构(OOP)和性能原因,建议注释中的双重间接可能不是一个好的解决方案.至少看起来很难定义std :: container3< B *>以及std :: container2< B>并跟踪不同交叉引用容器的结果动物园的有效性. 迭代器本质上具有指针语义.并且他们不应该要求引用类型的完整性. 如何处理C 14和之前的问题?

最佳答案 我用vector,list,deque,set和unordered_set尝试了你的第二个例子.仅对于unordered_set我得到了一个编译器错误,我可以通过使用指针容器来修复:

 using CA = std::unordered_set< A* >;
 using CB = std::unordered_set< B* >;

here(Ideone.com C 14).

点赞