gpt4 book ai didi

c++ - (boost::)outcome 的错误处理:在具有组合和继承的构造函数中使用

转载 作者:行者123 更新时间:2023-12-03 08:16:53 51 4
gpt4 key购买 nike

在我的环境中,我不能使用异常,所以我需要一个替代解决方案来处理错误。在新的现代项目中,将 int 作为错误代码返回不是一个好方法,因为此接口(interface)会阻止返回其他数据。
std::expected 尚不可用;也许有一些示例实现,但我需要一些已经测试过且健壮的东西。
我正在评估 (boost::) 结果 https://ned14.github.io/outcome/它似乎符合我的需求:它有一个清晰的界面,如果不使用辅助有效负载,它应该非常高效。
泛型类方法的用例非常简单:https://ned14.github.io/outcome/tutorial/essential/result/
关于构造函数的使用,作者建议使用双阶段构造(https://ned14.github.io/outcome/tutorial/advanced/constructors/)。
本教程不讨论类组合和继承。以下示例与教程相同。

class A {
protected: // use protected because of C class in the next example
constexpr A() noexcept { /*...*/ }
public:
~A() noexcept { /*...*/ }

A( A&& rhs ) noexcept { /*...*/ }

A& operator=( A&& rhs ) noexcept
{
this->~A();
new(this) A( std::move( rhs ) );
return *this;
}

// Remove copy ctor and assignment op
A( const A& ) = delete;
A& operator=( const A& ) = delete;

/** Static member constructor */
static result<A> A_ctor() noexcept
{
// Phase 1 ctor
A ret;
// Phase 2 ctor
if ( /*something goes wrong*/ ) return MyErrorCode::Error;
return { std::move( ret ) };
}

void a_method() noexcept { /*...*/ }
};

template<> struct make<A>
{
result<A> operator()() const noexcept
{
return A::A_ctor();
}
};
现在考虑包含类 A 的类 B。作为 protected A ctor,以下声明无效:
class B {
A a_;
...
};
也许以下方法可以工作:
class B {
result<A> a_;
constexpr B() noexcept : a_( make<A>{}() ) {}
public:
static result<B> B_ctor() noexcept
{
// Phase 1 ctor
B ret;
// Phase 2 ctor
if ( ret.value().a_.has_failure() ) return MyErrorCode::Error;
if ( /*something else goes wrong*/ ) return MyErrorCode::AnotherError;
return { std::move( ret ) };
}

// ...

void b_method() noexcept
{
a_.value().a_method(); // <-- ugly!
// ...
}
};
但使用 result<A>作为 a_ 的类型不是很好。它需要使用 a_.value()代码中的任何地方 a_用来。此外,如果 a_经常使用,可能会降低效率。还有其他解决方案吗?
派生类还有另一个暗点。
class C : public A {
constexpr C() noexcept : A() { /*...*/ }
public:
// ...

static result<C> C_ctor() noexcept
{
// Phase 1 ctor
C ret;
// Phase 2 ctor
// How to reuse A ctor???
// ...
return { std::move( ret ) };
}
};
C_ctor我想从 A_ctor 开始构建类(class)为避免代码重复,例如:
result<C> ret = C::A_ctor();
但没有可用的转换。有什么想法可以解决这个问题吗?

最佳答案

Being A ctor protected, the following declaration is not valid.


您确实不能使用不可访问的构造函数,但移动构造函数是公共(public)的,
所以你可以写你的 X_ctor不同:
B(A&& a) noexcept : a_(std::move(a)) {} // use public A(A&&)

static result<B> B_ctor() noexcept
{
result<A> a = make<A>();
if ( a.has_failure() ) return MyErrorCode::Error;

// Phase 1 ctor
B ret(std::move(a.value()));

// Phase 2 ctor
if ( /*something else goes wrong*/ ) return MyErrorCode::AnotherError;
return { std::move( ret ) };
}

In C_ctor I would like to construct the class starting from A_ctor to avoid code duplication


你可能有 init职能:
result<bool> init() noexcept 
{
// ...
if ( /*something goes wrong*/ ) return MyErrorCode::Error;
return {true};
}

static result<A> A_ctor() noexcept
{
// Phase 1 ctor
A ret;
// Phase 2 ctor
result<bool> a_init = ret.init();
if ( a_init.has_failure() ) return a_init.error();
return { std::move( ret ) };
}
result<bool> init() noexcept 
{
result<bool> a_init = A::init();
if ( a_init.has_failure() ) return a_init.error();

// ...
if ( /*something goes wrong*/ ) return MyErrorCode::Error;
return {true};
}

static result<C> C_ctor() noexcept
{
// Phase 1 ctor
C ret;

// Phase 2 ctor
result<bool> c_init = ret.init();
if ( c_init.has_failure() ) return c_init.error();
return { std::move( ret ) };
}

关于c++ - (boost::)outcome 的错误处理:在具有组合和继承的构造函数中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65415896/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com