我正在尝试将C API函数包装在某些情况下返回int
,而在其他情况下将指针返回到宏中,这将检查条件并提供诊断并在出现错误时抛出异常。对于返回int
的函数,它很简单,因为我不需要int
:
#define CALL_INT( name, ... ) do { \
if( !name( __VA_ARGS__ ) ) throw std::runtime_error( #name " failed" );
} while(0)
// using it
CALL_INT( foo, arg );
但是对于返回指针的函数来说并不那么简单,因为我需要检查指向nullptr
的指针,然后将其指定给我的指针。所以可以编写类似的宏,所以这个表达式可以工作:
auto ptr = CALL_PTR( foobar, arg1, arg2 );
即它会生成代码,调用foobar( arg1, arg2 )
检查nullptr
的结果,如果没有错误发生则可以分配。
答案 0 :(得分:3)
真正的解决方案是:不要使用宏。只要写下你想做的内联。你和其他所有人以后都会感谢你自己。
文字解决方案是立即调用lambda:
{{1}}
答案 1 :(得分:1)
魔法越少越好
#define VERIFY( ... ) \
[&](){
auto r = __VA_ARGS__;
if (!r) throw std::runtime_error( #__VA_ARGS__ " failed" );
return r;
}()
这需要一个表达。它运行它。然后测试它并在它失败时抛出。
如果失败,则包括throw中的整个表达式。
然后返回它。
由于VERIFY(bob)
正在做bob
,所以不那么神奇了。你可以做到
int x = VERIFY( call(a,b,c) );
或
VERIFY( y = call(a,b,c) );
或其他什么。主代码运行在那里;只有断言包装器失败时才会丢失。
VERIFY
也称为通常执行此操作的宏。