I try to create a non-copyable and non-movable class, whose object construction should only be done via a create function instead of public constructors. The create function will return a std::expected
object either holding the created object or an error object. In order to enforce construction via the create function I want to make all available constructors private. Main purpose of this approach is object construction without exceptions.
Here is a simple example:
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 }
{};
};
Please note, that I made std::expected<Foo, std::error_code>
a friend
in order to allow it to call the private constructor. But still I get a compiler error. Here is the code in Compiler Explorer.
You can use 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}; }
);
}