You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将不可移动不可复制的函数结果通过复制消除存入std::optional?

将不可移动不可复制类型存入std::optional(由自由函数构造)

给定如下不可移动、不可复制的类型Foo,以及返回该类型的自由函数foo():

struct Foo {
    Foo();
    Foo(Foo const&) = delete;
    Foo(Foo&&) = delete;
    Foo& operator=(Foo const&) = delete; // 为完整性添加
    Foo& operator=(Foo&&) = delete; // 为完整性添加
    ~Foo();
};
Foo foo();

在不修改Foo或foo()的前提下,我们可以通过复制消除直接构造对象:

Foo f1 = foo();

也能通过emplace()在std::optional内部默认构造Foo:

std::optional<Foo> f2;
f2.emplace();

但无法将foo()的结果存入std::optional:

f2 = foo(); // 编译失败:需要移动/复制Foo
f2.emplace(foo()); // 编译失败:Foo没有接受自身的构造函数

核心问题解答

确实没有办法实现这个需求,你并没有忽略什么。

原因在于:

  1. std::optional要存储已构造好的Foo对象,必须通过移动或复制操作将对象转移到自身的内部存储中,但Foo的移动和复制操作都被显式删除了。
  2. 虽然Foo f1 = foo();能通过复制消除直接在f1的内存中构造对象,但std::optional没有提供接口让foo()直接在其内部存储中构造Foo——emplace()方法仅支持调用Foo的构造函数来初始化内部对象,无法接收一个已构造好的Foo实例(因为传递实例需要移动/复制)。

除非你能修改foo(),让它直接在指定内存地址构造Foo(比如接受一个指针参数并在该位置用placement new构造),否则在现有约束下,无法将foo()返回的对象存入std::optional。


内容的提问来源于stack exchange,提问作者bitmask

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:25:56