std :: unordered_set按引用vs值返回类型

时间:2017-01-29 04:45:02

标签: c++ c++11 stl std

免责声明:我是c ++的新手。

我有一个像这样的代码块:

  using BucketType = std::unordered_set<Bucket, BucketHash, BucketEqual>;

  const BucketType& Range::buckets(int64_t value) {
    BucketType buckets;
    ...
    return std::move(buckets);
  }

调用者像这样调用这段代码:

  Range range;
  auto buckets = range.buckets(11);

问题:

当我像上面的代码一样返回桶的引用时,buckets.size()给出140732261909672但是,我只在实际逻辑中添加了2个桶。当我将代码更改为返回值而不是引用时,它完全正常。

有关此代码可能出错的指示吗?

1 个答案:

答案 0 :(得分:1)

让我们考虑一下您的buckets功能:

const BucketType& Range::buckets(int64_t value) {
    BucketType buckets;
    ...
    return std::move(buckets);
}

在这里创建一个BucketType类型的本地对象,移动到函数的返回值位置,然后返回 const reference bound到这个临时对象。毫无疑问,它会导致 Undefined Behavior

编写此类函数的正确方法是简化代码并摆脱const BucketType&std::move(buckets)

BucketType Range::buckets(int64_t value) {
    BucketType buckets;
    ...
    return buckets;
}

现在buckets可用于 NRVO (命名返回值优化)。这意味着所有现代编译器在这里执行 copy elision 并在使用{{初始化它们时直接构造BucketType对象(不在函数的返回值位置创建临时对象) 1}}功能:

buckets