交换两个 boost::adjacency_list 图,类似于 std::swap
Swapping two boost::adjacency_list graphs, akin to std::swap
我正在构建一个应用程序,其中包含 class DecoratedGraph
(比如说)使用 boost::adjacency_list
graph
作为基础成员。
我在 DecoratedGraph
中也有一些其他成员,其中一些成员将 std::map
和 std::vector
存储在 graph
的 vertices
上,代表各种附加属性。我将这些附加属性称为 decorations
.
我写了一个自定义复制构造函数,它不仅会复制图形,还会确保 decorations
引用 上的顶点,已复制图,非原图
根据 Rule of 3,除了复制构造函数,我们还需要复制赋值运算符和析构函数的定义 - 所以我也一直在实现这些。
对于复制赋值运算符,我使用了 another Whosebug answer 建议的复制和交换习惯用法。要为我的 class 实现交换功能,我需要同时交换 graph
和 decorations
。目前,我已经使用 std::map::swap
和 std::vector::swap
交换了 decorations
,并使用 std::swap
交换了两个对象的其他成员,包括 graph
.
然而,当我尝试在交换对象上使用 decorations
时,我发现引用不再引用 graph
上的顶点。我不确定我哪里出错了:我认为问题很可能在于 swap
函数没有按我预期的那样运行。 deocrations
上使用的 swap
分别是 std::map
和 std::vector
的成员方法——我希望它们能按预期运行。我怀疑可能有问题的地方是 std::swap
在 boost::adjacency_list
对象上的使用,这可能会产生意外行为。
我想知道 std::swap
是否是交换两个 boost::adjacency_list
graph
的正确方法?如果不是,正确的方法是什么?
的确,std::swap
好像不是你想要的。它选择 the generic 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);
}
这看起来不错,除了 Boost Graph 很大程度上早于 C++11,所以 actuvely 不使用移动语义。 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;
}
他们甚至不假装尝试移动。
做什么
根据您的装饰方式,您可能会使用 copy_graph 免费获得 home-run,它将复制内部属性以及捆绑属性和图形属性。
您需要手动复制外部 property maps(或您的 home-grown 等效项)。
Out-Of-The 盒子
使交换便宜 和 原子(考虑异常安全性!)的传统方法是使用 Pimpl 惯用语并仅交换实现指针。
我正在构建一个应用程序,其中包含 class DecoratedGraph
(比如说)使用 boost::adjacency_list
graph
作为基础成员。
我在 DecoratedGraph
中也有一些其他成员,其中一些成员将 std::map
和 std::vector
存储在 graph
的 vertices
上,代表各种附加属性。我将这些附加属性称为 decorations
.
我写了一个自定义复制构造函数,它不仅会复制图形,还会确保 decorations
引用 上的顶点,已复制图,非原图
根据 Rule of 3,除了复制构造函数,我们还需要复制赋值运算符和析构函数的定义 - 所以我也一直在实现这些。
对于复制赋值运算符,我使用了 another Whosebug answer 建议的复制和交换习惯用法。要为我的 class 实现交换功能,我需要同时交换 graph
和 decorations
。目前,我已经使用 std::map::swap
和 std::vector::swap
交换了 decorations
,并使用 std::swap
交换了两个对象的其他成员,包括 graph
.
然而,当我尝试在交换对象上使用 decorations
时,我发现引用不再引用 graph
上的顶点。我不确定我哪里出错了:我认为问题很可能在于 swap
函数没有按我预期的那样运行。 deocrations
上使用的 swap
分别是 std::map
和 std::vector
的成员方法——我希望它们能按预期运行。我怀疑可能有问题的地方是 std::swap
在 boost::adjacency_list
对象上的使用,这可能会产生意外行为。
我想知道 std::swap
是否是交换两个 boost::adjacency_list
graph
的正确方法?如果不是,正确的方法是什么?
的确,std::swap
好像不是你想要的。它选择 the generic 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);
}
这看起来不错,除了 Boost Graph 很大程度上早于 C++11,所以 actuvely 不使用移动语义。 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;
}
他们甚至不假装尝试移动。
做什么
根据您的装饰方式,您可能会使用 copy_graph 免费获得 home-run,它将复制内部属性以及捆绑属性和图形属性。
您需要手动复制外部 property maps(或您的 home-grown 等效项)。
Out-Of-The 盒子
使交换便宜 和 原子(考虑异常安全性!)的传统方法是使用 Pimpl 惯用语并仅交换实现指针。