5

unordered_set在 GCC 4.9 上移出,然后重用移出的对象时,当我添加它时,我得到一个被零除的结果。

我的理解(来自http://en.cppreference.com/w/cpp/utility/move)是,只要不违反任何先决条件,就可以使用移出的对象。调用clear()已移动的集合很好(这在前提条件的上下文中是有意义的),但我不清楚我是否通过添加新元素违反了任何前提条件。

示例代码:

#include <unordered_set>
using namespace std;
void foo(unordered_set<int> &&a) {
  unordered_set<int> copy = std::move(a);
}

void test() {
  unordered_set<int> a;
  for (int i = 0; i < 12; ++i) a.insert(i);
  foo(std::move(a));

  a.clear();
  a.insert(34); // divide by zero here
}

int main() {
  test();
}​

此代码在 GCC4.7 上运行良好 - 这是 GCC4.9unordered_set实现中的问题,还是我理解违反移出对象的先决条件意味着什么?

4

2 回答 2

9

这是PR 61143。它已针对 gcc-4.10 进行了修复,并且该修复程序已及时向后移植到 4.9.1。

于 2014-05-22T21:45:14.390 回答
3

Marc Glisse 已经向您介绍了 GCC 错误,但要回答您的问题:

这是一个问题吗……根据我对违反移出对象的先决条件意味着什么的理解?

不,不是,你的理解是正确的。使您的问题中的代码工作不仅仅是 GCC 扩展,您的程序是完全有效的。标准库中定义的类型的移出对象应该保持可用。您对其状态一无所知,但是,例如,任何容器都是空的或非空的,因此移出的容器也是空的或非空的。其中哪些是未指定的,但您的程序可以检查,并且标准库实现必须根据您的程序检查的结果进行适当的行为。

于 2014-05-22T21:50:34.870 回答