【问题标题】:Compile error with boost.graph 1.56.0 and g++ 4.6.4使用 boost.graph 1.56.0 和 g++ 4.6.4 编译错误
【发布时间】:2014-10-13 06:50:13
【问题描述】:

在尝试使用 Boost.Graph 时遇到了一些严重的编译错误。该错误是一种回归,因为它在编译 1.55.0 时不存在。我挖了一点,但无法修复,有人知道这里出了什么问题吗?

注意事项: 使用 -std=c++0x 编译标志

会产生错误的代码。

#include "boost/graph/adjacency_list.hpp"

int main(int argc, char** argv)
{
  using boost::adjacency_list;
  using boost::vecS;
  using boost::directedS;
  typedef adjacency_list<vecS, vecS, directedS, boost::default_color_type> Graph;

  std::vector< std::pair<int, int> > testVec;
  auto graph = Graph( begin(testVec), end(testVec), testVec.size());

  return 0;
}

从我的 IDE 复制的错误

/usr/include/c++/4.6/bits/vector.tcc:319:错误:使用已删除 函数'boost::detail::stored_edge_property::self& boost::detail::stored_edge_property::operator=(boost::detail::stored_edge_property::self&&) [with Vertex = long unsigned int, Property = boost::no_property, boost::detail::stored_edge_property::self = boost::detail::stored_edge_property]'

.../boost/boost/graph/detail/adjacency_list.hpp:318: 错误:'boost::detail::stored_edge_property::self& boost::detail::stored_edge_property::operator=(boost::detail::stored_edge_property::self&&) [with Vertex = long unsigned int, Property = boost::no_property, boost::detail::stored_edge_property::self = boost::detail::stored_edge_property]' 被隐式删除,因为默认 定义格式不正确:

.../boost/boost/graph/detail/adjacency_list.hpp:318:错误:基础 ‘boost::detail::stored_edge’ 没有动作 赋值运算符或普通复制赋值运算符

/usr/include/c++/4.6/bits/stl_algobase.h:546:错误:使用已删除 函数'boost::detail::stored_edge_property::self& boost::detail::stored_edge_property::operator=(boost::detail::stored_edge_property::self&&) [with Vertex = long unsigned int, Property = boost::no_property, boost::detail::stored_edge_property::self = boost::detail::stored_edge_property]'

【问题讨论】:

  • 您是否查看了 stored_edge 和 adjacency_list.hpp 从 1.55 到 1.56 的差异?答案可能就在里面。
  • 不错的主意,我去看看有什么不同。
  • 错误登录the boost bug tracker。还要注意的是,g++4.7或4.8不会出现编译错误,这是g++4.6特有的问题。
  • @radman 在 Ubuntu 上使用 gcc 4.8.5 和 boost 1.61 时,我遇到了这个错误。

标签: c++ gcc c++11 boost compiler-errors


【解决方案1】:

看来stored_edge_property(一个用于存储边缘属性的底层类)的实现已针对版本 1.55 到 1.56 之间的 C++11 右值引用进行了更新(您可以通过 diff'ing 清楚地看到它文件)。似乎他们忘记为其基类stored_edge 提供移动赋值运算符(并且由于存在复制赋值运算符而隐式禁用了默认运算符)。

这绝对是一个错误,应该向 Boost 报告。我记得他们在 1.48 版本前后犯了与shared_ptr 几乎相同的错误。我想人们并不总是从自己的错误中吸取教训。修复是微不足道的,但这确实应该在发布之前被捕获(这似乎是一个在单元测试中很容易捕获的错误)。请将您的发现报告给their bug tracker

N.B.:我经常使用 BGL,但我已经学会不信任他们的 adjacency_list 实现,尤其是在仔细研究过它之后。我现在使用我自己的实现(请参阅here),它消除了 BGL 携带的大量怪异实现的脂肪。

【讨论】:

  • 两个不同的 Boost 库相隔一两年犯了类似的错误并不奇怪,因为它们可能是由两组不同的人编写的。
  • 谢谢,实际上我刚刚解决了大部分问题,并回来解释它。澄清一点;在 detail/adjacency_list.hpp:319-21 默认说明符已用于 stored_edge_property 的移动操作符,你是说这不起作用,因为它的基础没有移动操作符?
  • 它无法工作,因为它的基类,称为stored_edge,有一个复制赋值运算符,根据 C++11 规则,它禁用了默认的(隐式)移动赋值运算符班级。如果基类中没有移动赋值运算符,编译器将无法为派生类生成默认的移动赋值运算符。修复应该像在基类中定义一个移动赋值运算符一样简单,类似于它已经拥有的复制赋值运算符(或者它甚至可以是一个显式默认的移动赋值运算符,我认为)。
  • 感谢 Mikael,默认 stored_edge 中的移动分配和移动构造函数成功了。我之前的解决方案是将 :302 上的条件更改为 4.7 及以下以排除 4.6,方便但不是正确的修复。我还验证了这不会发生在 4.7 或 4.8 上,有任何见解可能会发生这种情况吗?
  • @radman 我相信它适用于 4.7 和 4.8,因为编译器可以从 stored_edge 中选择复制赋值运算符,而不是隐式禁用的移动赋值运算符。我不确定规则是什么,但我确定复制分配的存在会禁用移动分配,并且我怀疑允许编译器选择基类复制分配而不是 move-assign 来实现默认的派生类 move-assignment。我的猜测是 4.6 有“禁用规则”,但无法选择基类 copy-assign 作为替代。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多