根据提案n4015 </e,>实施预期的<e,t =“”>

时间:2014-09-11 07:03:00

标签: c++ c++11

我根据提案开始实施expected<E, T>,但遇到了问题。 在描述monadic功能(5.9)时,在bind中声明如果结果已经包含在上下文中(expected<E, T>),则不应再次包装它。

我如何实现它是绑定有2个重载(带有enable_if),一个用于返回实例化expected的仿函数,实现没有将它包装在上下文中,一个用于那些返回了它做的其他类型。我遇到了一个问题,其中非包装版本,在调用者没有值的情况下必须返回默认的构造expected<E1, T1>,这给出了预期的默认构造错误值。

这导致返回的进一步延续预期会丢失导致默认构造的错误的上下文。

也许我应该对待被称为is_same<expected<E,T>, functor_ret_type>的上下文,这里如果调用者出错,我可以转发“this”并保留错误的上下文,但这会导致函数返回{ {1}}返回expected<E1, E2>

假设以下有关课程:

expected<E, expected<E1, E2>>

以下是我最初实施的方法:

E& error(); //returns the stored error
T& operator*(); //returns a reference to the stored value
bool has_value(); //returns true if the expected value is present, false if the error is present

在这里你可以看到,在第一个重载中,如果我们没有值,我们返回一个//overload for wrapping functors template<typename Functor> auto bind(Functor functor) -> std::enable_if<is_instance<expected, decltype(functor(**this))>::value, decltype(functor(**this))>::type { using result_type = decltype(functor(**this)); if (this->has_value()) { return functor(**this); } return result_type(); } //overload for non wrapping functors template<typename Functor> auto bind(Functor functor) -> std::enable_if<!is_instance<expected, decltype(functor(**this))>::value, expected<E, decltype(functor(**this))>>::type { using result_type = decltype(functor(**this)); if (has_value()) { return { functor(**this) }; } return expected<E, result_type>(this->error()); } 返回类型的默认构造expected<E, T>,它包含一个默认的构造错误类型{{1因为没有调用functor,我们会失去原始错误的上下文。

如果我将所描述的行为解释为“如果functor返回与调用绑定类型相同类型的functor,请不要换行换行”我们可以进行以下实现:

E

这里,如果包装重载中没有值,我们转发expected<E, T>,这可以让我们知道什么是初始错误,但如果functor返回//overload for wrapping functors template<typename Functor> auto bind(Functor functor) -> std::enable_if<is_same<expected<E, T>, decltype(functor(**this))>::value, decltype(functor(**this))>::type { if (this->has_value()) { return functor(**this); } return *this; } //overload for non wrapping functors template<typename Functor> auto bind(Functor functor) -> std::enable_if<!is_same<expected<E, T>, decltype(functor(**this))>::value, expected<E, decltype(functor(**this))>>::type { using result_type = decltype(functor(**this)); if (has_value()) { return { functor(**this) }; } return expected<E, result_type>(this->error()); } ,结果将是一个包裹this 1}}

我能想到的第三种方法是仅将expected<E1, T1>视为上下文,这种限制会稍微限制一些,并且允许解包返回expected<E, expected<E1, T1>>的仿函数,但问题是{ {1}}仍然存在。

哪种方法正确?也许我完全错过了另一种方法?

谢谢。

1 个答案:

答案 0 :(得分:1)

bind是根据unwrap

定义的
template <class Ex,class F>
’see below’ expected<E,T>::bind(F&& func)
     

返回:    - 如果bool(*this)返回unwrap(expected<E, decltype(func(move(val)))>(func(move(val)))),否则返回get_unexpected()

https://isocpp.org/files/papers/n4015.pdfhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4015.pdf unwrap中,只为expected<E,expected<E,U>>提供了非平凡的语义;也就是说,两个意外类型E必须相同:

template <class E, class U>
constexpr expected<E,U> expected<E,expected<E,U>>::unwrap() const&;
     

返回:    - 如果bool(*this)**this。别的get_unexpected()

如果有两种不同的意外类型E1E2unwrap无效。