gpt4 book ai didi

c++ - 为什么在 std::move 到抛出函数后成员 unique_ptr<> 保持非空?

转载 作者:行者123 更新时间:2023-12-03 13:19:51 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





std::move() is just casting?

(2 个回答)


1年前关闭。




当我 move 一个 unique_ptr<>进入一个抛出的函数, move 的指针是非空的。这是正常行为吗?

这是显示行为的两个测试程序。我可以在类的析构函数中观察到唯一指针:

#include <memory>
#include <iostream>

void f(std::unique_ptr<int> &&) { throw "fail"; }
struct except_move_tester
{
std::unique_ptr<int> x;
except_move_tester()
: x(std::make_unique<int>(0))
{}
~except_move_tester() { std::cout << "x at destructor: " << x.get() << std::endl; }
void g()
{
std::cout << "x at g: " << x.get() << std::endl;
f(std::move(x));
}
};

int main()
{
try {
except_move_tester t;
t.g();
} catch (...) {}
}

运行时给出输出:
x at g: 0x7f818b402ac0
x at destructor: 0x7f818b402ac0

如果我按如下方式修改上面的列表(只是在函数调用的位置添加了一个临时的),我会得到我通常期望的异常安全行为:
#include <memory>
#include <iostream>

void f(std::unique_ptr<int> &&) { throw "fail"; }
struct except_move_tester
{
std::unique_ptr<int> x;
except_move_tester()
: x(std::make_unique<int>(0))
{}
~except_move_tester() { std::cout << "x at destructor: " << x.get() << std::endl; }
void g()
{
std::cout << "x at g: " << x.get() << std::endl;
auto y = std::move(x);
f(std::move(y));
}
};

int main()
{
try {
except_move_tester t;
t.g();
} catch (...) {}
}

运行时给出输出:
x at g: 0x7f818b402ac0
x at destructor: 0x0

我一直在将 unique_ptr move 到函数中,假设它是一种原子异常安全操作,但这似乎表明异常可以使唯一指针处于意外状态。

最佳答案

std::move 只是将对象转换为右值,但不会执行 move 操作。
(强调我的)

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object.

In particular, std::move produces an xvalue expression that identifies its argument t. It is exactly equivalent to a static_cast to an rvalue reference type.


您的第二个代码段有效,因为您 move 了 x进入 y明确地。
要修复第一个片段,您还可以显式执行 move 操作,例如
void f(std::unique_ptr<int> && p) { 
std::unique_ptr<int> t = std::move(p); // move-construct t from p
throw "fail";
}
要不就
void f(std::unique_ptr<int> p) { throw "fail"; }
对于后者,给定 f(std::move(x)); ,参数 p从参数 x 移开.

关于c++ - 为什么在 std::move 到抛出函数后成员 unique_ptr<> 保持非空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58203185/

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