允许 std::expected 使用私有构造函数

问题描述 投票:0回答:1

我尝试创建一个不可复制且不可移动的类,其对象构造只能通过创建函数而不是公共构造函数来完成。 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
以便允许它调用私有构造函数。但我仍然收到编译器错误。这是Compiler Explorer中的代码。

c++ c++23
1个回答
0
投票

您可以使用

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>{42}.transform(
      [](int i) { return Foo{i}; }
    );
}

演示

© www.soinside.com 2019 - 2024. All rights reserved.