我想在std::optional
中存储一个不可移动且不可复制的 non-trivial 类型。但是该对象是由自由函数构造的。(example)
struct Foo {
Foo();
Foo(Foo const&) = delete;
Foo(Foo&&) = delete;
Foo& operator=(Foo const&) = delete; // added for completeness
Foo& operator=(Foo&&) = delete; // added for completeness
~Foo();
};
Foo foo();
不改变Foo
或foo()
;
多亏了复制省略,我已经可以做到这一点:
Foo f1 = foo();
这也可以编译,因为std::optional
只要求存储类型是可析构的:
std::optional<Foo> f2;
f2.emplace();
但是我不能用函数结果填充f2
:
f2 = foo(); // no
f2.emplace(foo()); // no
显然,因为这需要拷贝或移动Foo
。这可能是不可能的,但我是否忽略了什么?
3条答案
按热度按时间wh6knrhe1#
你可以创建一个类,其中转换操作符调用函数并返回结果,因为转换操作符将创建一个纯右值,所以你不需要类型是可复制/可移动的:
0s0u357o2#
我们可以利用
transform
(C++23中的新功能),它支持有保证的省略:这比
call_wrapper
稍微通用一些,因为它甚至在Foo
可以从call_wrapper
构造的情况下也能工作(因为,例如,它有一个接受所有内容的转换构造函数模板)。q1qsirdb3#
不确定这是否符合您不修改
Foo
或foo
的要求,但是您可以使用Bar
Package 器,该 Package 器默认通过调用foo
来初始化Foo
成员:我认为标题的答案是否定的。您不能将
Foo
复制或移动到optional
中,但通过 Package 器您可以在适当的位置构建它。