简体   繁体   English

交换两个 boost::adjacency_list 图,类似于 std::swap

[英]Swapping two boost::adjacency_list graphs, akin to std::swap

I'm building an application, which contains a class DecoratedGraph (say) making use of a boost::adjacency_list graph as an underlying member.我正在构建一个应用程序,其中包含一个类DecoratedGraph (比如说)使用boost::adjacency_list graph作为底层成员。

I have a bunch of other members in DecoratedGraph too, some of them storing std::map and std::vector on vertices of the graph , representing various additional properties.我在DecoratedGraph也有很多其他成员,其中一些将std::mapstd::vector存储在graph vertices上,代表各种附加属性。 I will refer to these additional properties as decorations .我将这些附加属性称为decorations

I have written a custom copy constructor, which would not only copy the graph but make sure that the decorations refer to the vertices on the copied graph, not the original graph.我编写了一个自定义复制构造函数,它不仅会复制图形,而且会确保decorations是指复制图形上的顶点,而不是原始图形。

According to the Rule of 3 , alongside the copy constructor, we also need a definition for the copy assignment operator and a destructor - and so I have been implementing these also.根据3 规则,除了复制构造函数之外,我们还需要一个复制赋值运算符和一个析构函数的定义——所以我也一直在实现这些。

For the copy assignment operator, I've made use of the copy-and-swap idiom, suggested by another stackoverflow answer .对于复制赋值运算符,我使用了另一个 stackoverflow answer建议的复制和交换习语。 To implement a swap function for my class, I would need to swap both the graph and the decorations .要为我的班级实现交换功能,我需要交换graphdecorations For now, I have used std::map::swap and std::vector::swap to swap the decorations , and used std::swap to swap the other members of the two objects, including the graph .现在,我使用std::map::swapstd::vector::swap来交换decorations ,并使用std::swap交换两个对象的其他成员,包括graph

However, when trying to make use of the decorations on my swapped object, I found that the references no longer refer to the vertices on the graph .但是,当尝试使用我交换的对象上的decorations时,我发现引用不再引用图上的graph I'm not certain where I have gone wrong: I believe the problem most likely lies in the swap function not behaving as I had expected.我不确定我哪里出错了:我认为问题很可能在于swap函数的行为不像我预期的那样。 The swap s used on the deocrations are the member methods for std::map and std::vector respectively - I would expect these to function as expected.swap在使用了s deocrations都为成员方法std::mapstd::vector分别-如预期我希望这些运作。 The one place that I suspect may be a problem is the usage of std::swap on boost::adjacency_list objects, which perhaps will have unexpected behaviour.我怀疑可能有问题的一个地方是在boost::adjacency_list对象上使用std::swap ,这可能会出现意外行为。

I'm wondering if std::swap is the correct way to go about swapping two boost::adjacency_list graph s?我想知道std::swap是否是交换两个boost::adjacency_list graph的正确方法? If not, what would be the correct approach?如果没有,正确的方法是什么?

Indeed, std::swap doesn't seem to be what you want.事实上, std::swap似乎不是你想要的。 It selects the generic std::swap that moves through a temporary, very simplified implementation:它选择通过临时的、非常简化的实现移动的通用std::swap

template <typename T> inline void swap(T& a, T& b) {
    T tmp = std::move(a);
    a = std::move(b);
    b = std::move(tmp);
}

This would seem fine, except that Boost Graph largely predates C++11 so doesn't actuvely use move semantics.这看起来很好,除了 Boost Graph 在很大程度上早于 C++11,所以并没有真正使用移动语义。 This is exemplified by the implementation of adjacency_list<>::swap member:这以adjacency_list<>::swap成员的实现为例:

void swap(adjacency_list& x)
{
    // Is there a more efficient way to do this?
    adjacency_list tmp(x);
    x = *this;
    *this = tmp;
}

They don't even pretend to try to move.他们甚至不会假装试图移动。

What To Do该怎么办

Depending on how you catered for your decorations, you might get a free home-run using copy_graph , which will copy internal properties as well as bundled properties and graph properties.根据您对装饰品的处理方式,您可能会使用copy_graph获得免费的本垒打,这将复制内部属性以及捆绑属性和图形属性。

You will want to manually replicate external property maps (or your home-grown equivalent of it).您将需要手动复制外部属性映射(或您自己开发的等效映射)。

Out-Of-The Box盒子外面

The conventional way to make swap both cheap and atomic (think about exception safety!) is to use Pimpl idiom and just swap the implementation pointers.使交换既便宜原子(考虑异常安全!)的传统方法是使用 Pimpl 惯用语并交换实现指针。

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

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