gpt4 book ai didi

c++ - 从 STL 堆栈/队列的顶部/前面 move 是否安全?

转载 作者:行者123 更新时间:2023-12-01 14:13:47 25 4
gpt4 key购买 nike

这个问题适用于堆栈和队列,但为了简单起见,我将在这里仅提及堆栈。

假设我们将非常量对象压入 std::stack,当我们从堆栈中弹出时,将堆栈顶部的对象 move 到临时对象中是否安全弹出之前的变量,如下所示:

std::stack<std::string> st;
st.emplace("asdf");
auto popped = std::move(st.top());
st.pop();

最佳答案

是的,如果您使用堆栈的非常量版本,它是安全的。 (对于 const 版本的堆栈,您很可能会复制对象或出现编译错误)

由于 std::stack 返回对对象的非常量引用,因此您可以随意修改它。这包括从对象中移出。

回想一下,从一个对象 move 会使它保持在有效状态(至少,如果类被正确实现的话)。它不会 摧毁它。它仍然在您的堆栈顶部。它只是不包含任何确定的值(value)。后续的 pop 将在其上调用适当的析构函数,没有问题。

注意,std::priority_queue不允许移出,因为这种容器实际上关心内容。并且 - 出于这个原因,它只返回一个 const-reference,它不能用于将内容从中移出。


响应 Iamanon 的观察,即 std::move 可以在 const 引用上执行。事实上,您可以做到这一点。通常它没有用,它通常会减少到拷贝,而不是 move 。考虑以下示例:

#include <iostream>
#include <string>
#include <stack>

class Foo {
public:
Foo() {
std::cout << "created\n";
}
~Foo() {
std::cout << "destroyed " << value << "\n";
}
Foo(const Foo& other) : value(other.value) {
std::cout << "copied\n";
}
Foo(Foo&& other) : value(other.value) {
other.value++;
std::cout << "moved\n";
}
Foo(const Foo&& other) : value(other.value) {
std::cout << "const-moved\n";
}
int value = 0;
};

int main()
{
std::stack<Foo> st;
st.emplace();
const std::stack<Foo>& cst = st;
auto popped = std::move(cst.top());
st.pop();
}

如果您运行上述程序,将使用 const-moved 版本。然而,当你实现你的 const-move 构造函数时,你会意识到你真的不能比你的常规复制构造函数做得更好。那是因为 other 保持不变。例如,您不能拥有任何 other 的所有权,并在 other 中重置它。

如果你删除了 const-move 构造函数,编译器将使用常规的复制构造函数。

如果复制构造函数被删除,并且只提供 move 构造函数 - 那么编译器会向你抛出一个错误。

关于c++ - 从 STL 堆栈/队列的顶部/前面 move 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61468001/

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