首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >引用stack<int>.top()在C++中的返回值的正确行为是什么

引用stack<int>.top()在C++中的返回值的正确行为是什么
EN

Stack Overflow用户
提问于 2013-08-12 05:32:53
回答 2查看 391关注 0票数 1

我对堆栈顶部元素的引用感到困惑。

代码语言:javascript
运行
复制
#include <iostream>
#include <stack>
using namespace std;

int main()
{
    stack<int> s;
    s.push(1);

    int        x = s.top();
    int&       y = s.top();
    const int& z = s.top();

    cout << x << '\t' << y << '\t' << z << endl;

    s.pop();
    s.push(2);

    cout << x << '\t' << y << '\t' << z << endl;
}
/* Output:
1       1       1
1       2       2
 */

我认为不应该更改对top元素的引用,但是在将一个新元素推入堆栈之后,引用所引用的值将被更改。

这对我来说很奇怪,因为如果堆栈的类型不是int,假设它是MyClass类型(非常大的数据),那么有什么方法可以安全地引用旧的top元素吗?(因为我不想做昂贵的复制操作)。

我想这种行为可能是依赖于实现的,签名!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-12 05:58:40

如C++11标准所述(23.6.5.2 - stack定义)

代码语言:javascript
运行
复制
reference top() { return c.back(); }
const_reference top() const { return c.back(); }
...
void push(const value_type& x) { c.push_back(x); }
void push(value_type&& x) { c.push_back(std::move(x)); }
...
void pop() { c.pop_back(); }

在使用默认的底层容器std::deque时,iterator/reference invalidation rules声明(引用this答案):

deque:擦除最后一个元素只使迭代器无效和对擦除元素和过去结束迭代器的引用无效;擦除第一个元素只使迭代器无效和对擦除元素的引用无效;擦除任何其他元素使所有迭代器和引用(包括过去-结束迭代器)都无效。

通过使用std::stack::pop,您必须调用std::deque::pop_back(),如前所述,使以前返回的引用无效(后者随后调用std::deque::back())。因此,您不应该依赖这种行为,因为它是未定义的,不可移植的,而且是错误的。

如果您想拥有堆栈顶部的原始值,那么解决方案就是复制top元素,而不是引用它。也就是说,如果您想在从堆栈中弹出一个元素之后正确地保留原始值。

票数 3
EN

Stack Overflow用户

发布于 2013-08-12 05:41:53

在pop()之后,引用无效。输出显示了由于std::堆栈的实现细节而产生的新推送值--不要依赖它,它也可能是垃圾。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18180127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档