C++ C/C++;用于空安全指针访问的宏

C++ C/C++;用于空安全指针访问的宏,c++,c,pointers,null,macros,C++,C,Pointers,Null,Macros,我想为空安全指针访问编写一个C/C++宏。我目前有一个很好用的: #define NULL_SAFE(p, e) if (p) p->e NULL_SAFE(myPtr, myMethod(myArg)); 但我真正想要的是这样的东西: NULL_SAFE( myPtr, myMethod(myArg), myOtherPtr, myOtherMethod(myOtherArg), yetAnotherMyPtr, plsStopMethod(grArg), ... );

我想为空安全指针访问编写一个C/C++宏。我目前有一个很好用的:

#define NULL_SAFE(p, e) if (p) p->e
NULL_SAFE(myPtr, myMethod(myArg));
但我真正想要的是这样的东西:

NULL_SAFE(
  myPtr, myMethod(myArg),
  myOtherPtr, myOtherMethod(myOtherArg),
  yetAnotherMyPtr, plsStopMethod(grArg),
  ...
);
这将扩展到:

  if (myPtr) myPtr->myMethod(myArg);
  if (myOtherPtr) myOtherPtr->myOtherMethod(myOtherArg);
  if (yetAnotherMyPtr) yetAnotherMyPtr->plsStopMethod(grArg);
我可以想到一大堆我可能想用的,但它们都是在同一个概念上运作的


这可能吗?这已经存在于某处了吗?有什么建议吗?谢谢你的帮助

如果空检查是算法的一部分,那么只需显式键入空检查,而不需要任何讨厌的宏


如果NULL检查是一种防御性编程方法,那么正确的方法是
assert(ptr)。如果断言曾经触发过,请修复导致它的错误。重复此操作,直到没有错误,然后从产品质量代码中删除断言。

我能做到的最接近的方法是使用c++11可变模板和C99可变宏。。。抱歉,如果你的平台不允许它,不管它是伟大的乐趣拿出代码

#include <functional>
#include <iostream>

template<class T>
void stuff(T a)
{
    std::cout<< "stuff:" << a << std::endl;
}

template<class T>
void other_stuff(T a)
{
    std::cout<< "other_stuff:" << a << std::endl;
}

template <typename Test, typename ToCall>
void tester(Test t, ToCall tc)
{
    if(t) tc();
}

template <typename Test, typename ToCall, typename... Others>
void tester(Test t, ToCall tc, Others... args)
{
    if(t) tc();
    tester(args...);
}

#define FUN_WRAP(a,b) std::bind(a<decltype(b)>, (b) )
#define NULL_SAFE(...) tester(__VA_ARGS__)

int main()
{
    NULL_SAFE(1, FUN_WRAP(stuff, 1),
        0, FUN_WRAP(stuff, 2),
        1, FUN_WRAP(other_stuff, 3)
        );
}
#包括
#包括
模板
无效材料(TA)
{
std::coutC++11:

您还可以使用任何谓词作为第一个参数


为什么它是空的,而不是Null pTR作为读者的练习。< /P>你使用C还是C++?如果使用C++你可能想要使用智能指针。宏看起来是一个很好的东西,但是经常会使代码难以读取和维护。所以我的建议是不要用宏来代替它,使用显式代码代替。比宏更好的是一个函数。ion获取指针和要在其上执行的内容:

nullSafe(myPtr,[&](auto&pointee){pointee.myMethod(myArg);}那时,你基本上有一个
可选的
和一个
映射
函数。我真的不明白这样的泛型函数是如何有用的。通常,当你做空检查时,你必须以某种方式处理空值条件。在什么情况下你只想取消引用有效的指针,而simp在这种情况下,使用像std::map这样的容器不是更好吗?如果指针为null,您是否真的通过默默地跳过语句获得了一些东西?我更喜欢一个很好的崩溃,显示程序的bug。(另一个故事是名为if_NOT_null的宏)除非空指针是程序的可接受状态。请参阅我对CodyGray评论的回复。谢谢你的建议!这看起来很好,但是一旦你有了变量模板函数,你甚至需要空\u安全宏吗?另外,我正在寻找一个宏,因此它对于c++11之前的编译器和c来说是可移植的,但是如果它打开了,这将是一个很好的选择一个纯粹的宏解决方案是不可能的!@RoboCop87:一个纯粹的宏解决方案是可能的。但是这太恶心了,不能认真思考。不,你真的不需要
NULL\u-SAFE
宏。@JohnZwinck“太恶心了,不能认真思考”这让我想学习如何做得更多,如果不仅仅是为了学术练习!我必须用谷歌搜索那一个。nullptr计算为指针类型,而nullptr计算为整数,这显然是模板工作所必需的。感谢练习!如果走模板之路,您可能会将参数传递给函数。。。
inline void null_safe()
{
}

template <typename Ptr, typename Fn, typename... Args>
void null_safe(Ptr&& ptr, Fn&& fn, Args&&... args)
{
    if (ptr)
        fn();
    // you could put "else" here                                                                                                            
    null_safe(std::forward<Args>(args)...);
}
int f2() {
    return printf("f2\n");
}

int f3() {
    return printf("f3\n");
}

int main()
{
    int i1 = 1;

    null_safe(
        &i1, f2
        );

    null_safe(
        NULL, f2,
        &i1, f3
        );
}