C ++是否有安全的导航运算符? [英] Is there a safe navigation operator for C++?

查看:79
本文介绍了C ++是否有安全的导航运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在现代C ++中,有没有一种方法可以进行安全的导航?

In Modern C++, is there a way to do safe navigation?

例如,代替这样做...

if (p && p->q && p->q->r)
    p->q->r->DoSomething();

...通过使用某种短路智能指针或其他某种语法,具有简洁的语法

...having a succinct syntax by using some sort of short-circuiting smart pointer, or some other kind of syntax leveraging operator overloading, or something in the Standard C++ Library, or in Boost.

p?->q?->r?->DoSomething(); // C++ pseudo-code.

上下文特别是C ++ 17。

Context is C++17 in particular.

推荐答案

您能做的最好的就是将所有成员访问都折叠为一个函数。假设不检查所有内容是否都是指针:

The best you can do is collapse all the member accesses into one function. This assumes without checking that everything is a pointer:

template <class C, class PM, class... PMs>
auto access(C* c, PM pm, PMs... pms) {
    if constexpr(sizeof...(pms) == 0) {
        return c ? std::invoke(pm, c) : nullptr;
    } else {
        return c ? access(std::invoke(pm, c), pms...) : nullptr;
    }
}

哪个让你这样写:

if (auto r = access(p, &P::q, &Q::r); r) {
    r->doSomething();
}

没关系。或者,您可能会因运算符重载而有点疯狂,并产生类似以下内容的东西:

That's ok. Alternatively, you could go a little wild with operator overloading and produce something like:

template <class T>
struct wrap {
    wrap(T* t) : t(t) { }
    T* t;

    template <class PM>
    auto operator->*(PM pm) {
        return ::wrap{t ? std::invoke(pm, t) : nullptr};
    }

    explicit operator bool() const { return t; }
    T* operator->() { return t; }
};

可以让您这样写:

if (auto r = wrap{p}->*&P::q->*&Q::r; r) {
    r->doSomething();
}

也可以。不幸的是,没有->?。?之类的运算符,因此我们有点需要努力工作。

That's also ok. There's unfortunately no ->? or .? like operator, so we kind of have to work around the edges.

这篇关于C ++是否有安全的导航运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆