在Modern C中,有没有办法安全导航?
例如,而不是……
if (p && p->q && p->q->r)
p->q->r->DoSomething();
…通过使用某种短路智能指针或其他一些利用运算符重载的语法或标准C库或Boost中的某些东西,具有简洁的语法.
p?->q?->r?->DoSomething(); // C++ pseudo-code.
上下文特别是C 17.
解决方法:
您可以做的最好的事情是将所有成员访问权限折叠为一个函数.这假定没有检查一切都是指针:
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();
}
没关系.或者,您可能会因为运算符重载而变得有点疯狂,并产生如下内容:
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();
}
那也没关系.遗憾的是没有 – >?要么 .?像运算符一样,所以我们必须围绕边缘工作.