我想为空安全指针访问编写一个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);
我可以想到我可能想要使用的一大堆这些,但它们都运行在与此相同的概念上。
这可能吗?这已经存在于某个地方吗?有什么建议?谢谢你的帮助!
答案 0 :(得分:5)
如果NULL检查是算法的一部分,那么只需显式地键入NULL检查,而不需要任何icky宏。
如果NULL检查是一种防御性编程方式,那么执行此操作的正确方法是assert(ptr);
。如果断言触发,请修复导致它的错误。重复,直到没有错误,然后从生产质量代码中删除断言。
答案 1 :(得分:3)
C ++ 11:
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)...);
}
您可以使用任何callable作为第二个参数,所以:
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
);
}
您也可以使用任何谓词作为第一个参数。
为什么它在那里是NULL而不是nullptr留给读者的练习。
答案 2 :(得分:1)
我能得到的最接近的是使用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)
);
}