我尝试创建一个不可复制且不可移动的类,其对象构造只能通过创建函数而不是公共构造函数来完成。 create 函数将返回一个std::expected
包含已创建对象或错误对象的对象。为了通过创建函数强制构造,我想将所有可用的构造函数设为私有。这种方法的主要目的是无例外地构造对象。
这是一个简单的例子:
class Foo
{
int val_{};
public:
Foo() = delete;
Foo(const Foo&) = delete;
Foo& operator=(const Foo&) = delete;
static auto
create(int val) noexcept -> std::expected<Foo, std::error_code>
{
if (val == 42)
return std::unexpected<std::error_code>(std::in_place, EINVAL, std::generic_category() );
return std::expected<Foo, std::error_code>{ std::in_place, val };
}
private:
friend class std::expected<Foo, std::error_code>;
explicit Foo(int val) noexcept
: val_{ val }
{};
};
请注意,我做了std::expected<Foo, std::error_code>
一个friend
以便允许它调用私有构造函数。但我仍然收到编译器错误。这是中的代码。
3
1 个回答
1
您可以使用expected::transform
:
static auto
create(int val) noexcept -> std::expected<Foo, std::error_code>
{
if (val == 42)
return std::unexpected<std::error_code>(std::in_place, EINVAL, std::generic_category() );
return std::expected<int, std::error_code>{val}.transform(
[](int i) { return Foo{i}; }
);
}
3
-
2好的! …而且它甚至不需要
friend
船!
–
-
该解决方案令人印象深刻并解决了问题。然而,考虑到这可能是无异常编程的常见用例,它是一个相当麻烦的解决方案。令人遗憾的是,语言无法以更好的方式支持这一点。
– -
1@k.st。支持不可移动类型并不是“无异常编程的常见用例”。
–
|
return Foo{val};
?–
return Foo{val};
不起作用:–
–
|