c++ - 如何在不调用析构函数的情况下将值移出 std:optional ?
问题描述
我正在尝试编写一个函数,make_foo
它将“解包” a std::optional< foo >
,返回包含的值。该函数假定可选选项已启用,因此不对optional
.
下面是我的实现,以及编译的程序集以供参考。我有几个关于编译器输出的问题:
为什么这会导致代码分支?
optional::operator*
提供对包含值的未经检查的访问,所以我不希望看到任何分支。为什么
foo
会调用析构函数?注意on_destroy()
程序集中的调用。我们如何在不调用析构函数的情况下将包含的值移出可选值?
C++17 源代码
#include <optional>
extern void on_destroy();
class foo {
public:
~foo() { on_destroy(); }
};
extern std::optional< foo > foo_factory();
// Pre-condition: Call to foo_factory() will not return nullopt
foo make_foo() {
return *foo_factory();
}
优化的编译器输出 (Clang 11)
make_foo(): # @make_foo()
push rbx
sub rsp, 16
mov rbx, rdi
lea rdi, [rsp + 8]
call foo_factory()
cmp byte ptr [rsp + 9], 0
je .LBB0_2
mov byte ptr [rsp + 9], 0
call on_destroy()
.LBB0_2:
mov rax, rbx
add rsp, 16
pop rbx
ret
解决方案
你的方法或多或少是这样的:
foo make_foo() {
auto x = foo_factory();
return *x;
}
从工厂返回的产品在哪里x
(optional
代码中未命名的临时文件)。当x
被销毁时,它要么调用所包含对象的析构函数(当有一个时)。或者它不会破坏包含的对象(当没有对象时)。简而言之:foo
您从中移出的仍然需要被销毁,即使您知道可选项确实包含它,编译器也不能,因此分支。
如何在不调用析构函数的情况下将值移出 std:optional ?
你不能。即使是从对象移动的最终也需要被销毁。
推荐阅读
- java - 验证 @NotBlank 不适用于 @JsonProperty
- python - 正确使用 Python re.groupdict()
- spring-boot - Azure Devops Docker Push:本地不存在带有标记的映像
- c# - 如何从 C# 中的 JSON 对象获取值?如果未定义键
- sql - 在 Oracle 12c/PL SQL 中查找给定 IP 地址和前缀长度的子网地址
- excel - 切换功能 Excel
- java - 在屏幕上搜索图像时如何跳过透明像素?
- laravel - Laravel 逐行调试
- adonis.js - 验证器在 Adonis Resorceful 路线中不起作用
- javascript - 将分类器输出限制在“0”和“1”之间