免责声明:我是 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