gpt4 book ai didi

c++ - 返回在 C++ 中没有 back() 方法的容器的最后一个元素?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:40:49 25 4
gpt4 key购买 nike

在不提供 back() 成员函数(例如 std::set)的容器中返回最后一个元素的最佳方法是什么?

由于 end() 方法返回指向容器末尾后第一个元素的迭代器,是否是获取最后一个元素以在取消引用之前递减迭代器的唯一方法?

如:

std::set<int> set = {1,2,3,4,5};

int end = *(set.end());
int beforeEnd = *(--set.end());

std::cout << "set.end() -> " << end << std::endl;
std::cout << "--set.end() -> " << beforeEnd << std::endl;

然而,这些都返回:

set.end() -> 5
--set.end() -> 5

这是获取最后一个元素的正确方法吗?为什么它们返回相同的值?

最佳答案

这个

int end = *(set.end());

正如 πάντα ῥεῖ 评论的那样, 具有未定义的行为。那是因为 std::set::end

Returns an iterator to the element following the last element of the container. This element acts as a placeholder; attempting to access it results in undefined behavior. (https://en.cppreference.com/w/cpp/container/set/end, emphasis mine)

另一行:

int beforeEnd = *(--set.end());

它不能保证工作。参见例如https://en.cppreference.com/w/cpp/iterator/prev ,强调我的:

Although the expression --c.end() often compiles, it is not guaranteed to do so: c.end() is an rvalue expression, and there is no iterator requirement that specifies that decrement of an rvalue is guaranteed to work. In particular, when iterators are implemented as pointers, --c.end() does not compile, while std::prev(c.end()) does.

因此它可能会因为无法编译的相同原因而失败:

int arr[4] = {1,2,3,4};
int *p = --(arr + 4); // --> error: expression is not assignable

您可以改为编写如下内容。

std::set<int> set = {1,2,3,4,5};

if ( set.begin() != set.end() )
{
auto itLast = std::prev(set.end());

std::cout << "last -> " << *itLast << '\n';
}

关于c++ - 返回在 C++ 中没有 back() 方法的容器的最后一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55712753/

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