【问题标题】:Validating a chain of pointers [duplicate]验证指针链[重复]
【发布时间】:2018-10-22 09:45:30
【问题描述】:

为避免异常,必须在使用内部指针之前检查指针链中的每个指针。

有没有现代的c++语法,或者一些简单的方法来代替繁琐的:

if (pA && pA->pB && pA->pB->pC)
    pA->pB->pC->DoYerThing();

变成下面这样的东西?

if(not_nullptrs(pA->pB->pC))
    pA->pB->pC->DoYerThing();

【问题讨论】:

  • "为了避免异常" - 取消引用 nullptr 或未初始化的指针not 会导致异常。它会导致未定义的行为。
  • 我认为我不需要编写这样的代码。你的用例是什么?
  • TL;DR:不,没有。泄漏并不得不挖掘多个级别的实现细节是代码异味。我建议你重新考虑你的设计。
  • 不使用 STL 类型(还)或常规指针。但是为带有绑定/映射指令的指针(a-la Rust 或几乎任何其他类似类型的语言)编写自己的简单 optional 是非常简单的。这样你就可以写pA.bind([&](auto p){ return pB; }).bind(...),你明白了。见open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0798r0.html
  • @DanM.: 这与我的问题完全一致...

标签: c++ syntax


【解决方案1】:

这是罗密欧建议的固定版本:

template <typename X0>
auto safe_chain(X0* x0)
{
    return x0;
}

template <typename X0, typename X1, typename... Xs>
auto safe_chain(X0* x0, X1 x1, Xs... xs)
{
    return x0
        ? safe_chain(x0->*x1, xs...)
        : nullptr;
}


// usage
struct C {
    void DoYerThing();
};
struct B {
    C* pC;
};
struct A {
    B* pB;
};

if(auto p = safe_chain(pA, &A::pB, &B::pC))
    p->DoYerThing();

这并不容易阅读。 pA &amp;&amp; pA-&gt;pB &amp;&amp; pA-&gt;pB-&gt;pC 就好了。

惯用的解决方案通常是尽可能依赖引用,以便将空指针检查限制在尽可能少的范围内。当确实需要指针时,应使用函数(可能是*pA 的成员函数)以避免重复检查。

【讨论】:

  • safe_chain 甚至可以更通用并支持智能指针。
  • @Jarod42 也许......我也没有在副本中看到这样的例子。愿意展示你如何实现它吗?
  • std::invoke 负责处理,IIRC。
  • 感谢您修正我的想法,没有时间测试它,但我很高兴看到我离我不远了:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多