c++ - std::unordered_set 通过引用与值返回类型

标签 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 个桶.当我将代码更改为返回值而不是引用时,它工作得很好。

关于这段代码可能有什么问题的任何指示?

最佳答案

让我们考虑一下您的buckets 函数:

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

这里你创建了一个BucketType类型的本地对象,移动它到函数的返回值位置,然后返回绑定(bind)到的常量引用这个临时对象。毫无疑问,它会导致未定义的行为

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

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

现在 buckets 可用于 NRVO(命名返回值优化)。这意味着所有现代编译器都在此处执行复制省略并在使用 初始化时直接构造 BucketType 对象(无需在函数的返回值位置创建临时对象)桶函数:

auto buckets = range.buckets(11); // No unnecessary copies here

关于c++ - std::unordered_set 通过引用与值返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41917681/

相关文章:

c++ - 是否为包含相同值的范围定义了 std::nth_element?

c++ - 尝试读取对象 vector 时程序崩溃

c++ - sql参数的最佳STL容器

c# - 我应该使用 return/continue 语句而不是 if-else 吗?

c++ - 使用数组填充对称矩阵

c++ - 如何使用 std::bind 将函数与对象指针参数绑定(bind)?

c++ - 在编译时更改字符串宏

c++ - C++中原始STL实现中 "construct"方法逻辑的理解

c++ - 使用 std::vector 时处理内存

c++ - 如何向 Boost.Tuple 添加元素