免责声明:我是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个桶。当我将代码更改为返回值而不是引用时,它完全正常。
有关此代码可能出错的指示吗?
答案 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