gpt4 book ai didi

c++ - 避免未定义的行为 : temporary objects

转载 作者:行者123 更新时间:2023-12-02 10:02:13 26 4
gpt4 key购买 nike

我写了一个类来使用它作为一个方便的 View ,例如基于范围的for s。总的来说,它只是一对带有边界检查的迭代器:

template<typename I> class Range {
private:
I begin;
I end;

public:
Range(I const begin, I const end)
: begin(begin), end(end)
{}

Range<I>& skip(int const amount) {
begin = std::min(begin + amount, end);
return *this;
}
};

template<typename C> auto whole(C const& container) {
using Iterator = decltype(std::begin(container));
return Range<Iterator>(std::begin(container), std::end(container));
}

这是它的预期用途(导致 UB):
std::vector<int> const vector{1, 2, 3};
for (int const value : whole(vector).skip(1)) {
std::cout << value << ' ';
}

删除 skip(1)部分有帮助,与 Range::skip 的以下重构相同:
Range<I> skip(int const amount) const {
I const new_begin = std::min(begin + amount, end);
return Range<I>(new_begin, end);
}

似乎临时不能返回对自身的引用。这是 cppreference 所说的:

All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created, and if multiple temporary objects were created, they are destroyed in the order opposite to the order of creation.



虽然我不确定情况是否如此,但我现在不知道如何实际解释它。实际问题是什么,我怎样才能可靠地避免这种 UB?是相似的表达方式,例如 auto string = std::string("abc").append("def")也不安全?

最佳答案

ranged-based for loop范围表达式必须引用为(原型(prototype)代码)

auto && __range = whole(vector).skip(1) ;

问题是 whole(vector) 创建的临时文件在完整表达式后立即销毁,引用 __range (绑定(bind)到从 skip 返回的引用,即临时的)变得悬空;之后任何取消引用都会导致 UB。
auto string = std::string("abc").append("def")很好, string被复制,它是一个独立于临时 std::string 的对象.

从 C++20 开始,您可以添加 init-statement :

If range_expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the forwarding reference __range, but beware that the lifetime of any temporary within range_expression is not extended.



例如。
std::vector<int> const vector{1, 2, 3};
for (auto thing = whole(vector); int const value : thing.skip(1)) {
std::cout << value << ' ';
}

关于c++ - 避免未定义的行为 : temporary objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62082049/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com