Wil*_*nan 7 c++ optional c++17
如何避免在 C++ 中使用链式选项嵌套 if 语句?
例如,如果类型 A 包含 anstd::optional<B> b和类型 B an std::optional<C> c,我希望能够编写如下内容:
const auto v = if_exists(if_exists(a->b)->c);
Run Code Online (Sandbox Code Playgroud)
如果 b 或 c 是空可选项,则 v 将从 c 或空可选项中获取值。
我认为这样嵌套 ifs 会更好:
if (a->b) {
const auto b = *(a->b);
if (b->c) {
const auto c = *(b->c);
}
}
Run Code Online (Sandbox Code Playgroud)
以下问题似乎朝这个方向发展,但我不确定如何将其调整到我的用例中:Haskell style "Maybe" type & *chaining* in C++11
您可以执行类似的操作(伪代码;下面提供了可构建代码的链接):
// wrap std::optional for chaining
template <class T> class Maybe {
std::optional<T> t;
// ... constructors etc
// Maybe chaining
// If A has a member named m of type M,
// then Maybe<A>.fetch(&A::m) returns a Maybe<M>
template <class M>
Maybe<M> fetch(M T::*mem_ptr) {
return (bool(t)) ? Maybe<M>((*t).*mem_ptr) : Maybe<M>() ;
}
// Maybe chaining special case
// If A has a member named m, which is itself a Maybe<M>,
// then return it without wrapping it in an additional Maybe
template <class M>
Maybe<M> fetch(Maybe<M> T::*mem_ptr) {
return (bool(t)) ? ((*t).*mem_ptr) : Maybe<M>() ;
}
};
Run Code Online (Sandbox Code Playgroud)
现在如果你有这个:
struct C { int d ; }
struct B { C c; }
struct A { B b; }
A a;
Maybe<A> ma;
Run Code Online (Sandbox Code Playgroud)
你可以这样做
int d = a.b.c.d;
Run Code Online (Sandbox Code Playgroud)
您不能对 执行相同的操作ma,但您可以使用下一个最好的方法,即:
Maybe<int> md = ma.fetch(&A::b).fetch(&B::c).fetch(&C::d);
Run Code Online (Sandbox Code Playgroud)
Maybe如果您-ifystruct上面的任何或所有成员,您仍然可以使用它:
struct C { Maybe<int> d ; }
struct B { Maybe<C> c; }
struct A { Maybe<B> b; }
Run Code Online (Sandbox Code Playgroud)