Suppose I have a C++ macro CATCH to replace the catch statement and that macro receive as parameter a variable-declaration regular expression, like <type_name> [*] <var_name>
or something like that. Is there a way to recognize those "fields" and use them in the macro definition?
假设我有一个C ++宏CATCH来替换catch语句,并且宏接收变量声明正则表达式作为参数,如
For instance:
#define CATCH(var_declaration) <var_type> <var_name> = (<var_type>) exception_object;
Would work just like:
会像以下一样工作:
#define CATCH(var_type, var_name) var_type var_name = (var_type) exception_object;
As questioned, I'm using g++.
如被质疑,我正在使用g ++。
3 个解决方案
#1
You can't do it with just macros, but you can be clever with some helper code.
你不能只用宏来做,但你可以聪明地使用一些帮助代码。
template<typename ExceptionObjectType>
struct ExceptionObjectWrapper {
ExceptionObjectType& m_unwrapped;
ExceptionObjectWrapper(ExceptionObjectType& unwrapped)
: m_unwrapped(unwrapped) {}
template<typename CastType>
operator CastType() { return (CastType)m_wrapped; }
};
template<typename T>
ExceptionObjectWrapper<T> make_execption_obj_wrapper(T& eobj) {
return ExceptionObjectWrapper<T>(eobj);
}
#define CATCH(var_decl) var_decl = make_exception_obj_wrapper(exception_object);
With these definitions,
有了这些定义,
CATCH(Foo ex);
should work. I will admit to laziness in not testing this (in my defence, I don't have your exception object test with). If exception_object can only be one type, you can get rid of the ExceptionObjectType template parameter. Further more, if you can define the cast operators on the exception_object itself you can remove the wrappers altogether. I'm guessing exception_object is actually a void* or something though and your casting pointers.
应该管用。我会承认懒惰不测试这个(在我的辩护中,我没有你的异常对象测试)。如果exception_object只能是一种类型,则可以删除ExceptionObjectType模板参数。此外,如果您可以在exception_object本身上定义强制转换运算符,则可以完全删除包装器。我猜是exception_object实际上是一个void *或者其他东西和你的铸造指针。
#2
What compiler are you using? I've never seen this done in the gcc preprocessor, but I can't say for sure that no preprocessor out there can implement this functionality.
你用的是什么编译器?我从未在gcc预处理器中看到过这种情况,但我不能肯定地说没有预处理器可以实现这个功能。
What you could do however is run your script through something like sed to do your prepreprocessing so to speak before the preprocessor kicks in.
然而,你可以做的是通过像sed这样的东西运行你的脚本进行预处理,以便在预处理器启动之前说出来。
#3
Hmmm... I'm just guessing, but why don't you try something like this : :)
嗯......我只是猜测,但你为什么不尝试这样的东西::)
#define CATCH(varType,varName) catch(varType& varName) { /* some code here */ }
#1
You can't do it with just macros, but you can be clever with some helper code.
你不能只用宏来做,但你可以聪明地使用一些帮助代码。
template<typename ExceptionObjectType>
struct ExceptionObjectWrapper {
ExceptionObjectType& m_unwrapped;
ExceptionObjectWrapper(ExceptionObjectType& unwrapped)
: m_unwrapped(unwrapped) {}
template<typename CastType>
operator CastType() { return (CastType)m_wrapped; }
};
template<typename T>
ExceptionObjectWrapper<T> make_execption_obj_wrapper(T& eobj) {
return ExceptionObjectWrapper<T>(eobj);
}
#define CATCH(var_decl) var_decl = make_exception_obj_wrapper(exception_object);
With these definitions,
有了这些定义,
CATCH(Foo ex);
should work. I will admit to laziness in not testing this (in my defence, I don't have your exception object test with). If exception_object can only be one type, you can get rid of the ExceptionObjectType template parameter. Further more, if you can define the cast operators on the exception_object itself you can remove the wrappers altogether. I'm guessing exception_object is actually a void* or something though and your casting pointers.
应该管用。我会承认懒惰不测试这个(在我的辩护中,我没有你的异常对象测试)。如果exception_object只能是一种类型,则可以删除ExceptionObjectType模板参数。此外,如果您可以在exception_object本身上定义强制转换运算符,则可以完全删除包装器。我猜是exception_object实际上是一个void *或者其他东西和你的铸造指针。
#2
What compiler are you using? I've never seen this done in the gcc preprocessor, but I can't say for sure that no preprocessor out there can implement this functionality.
你用的是什么编译器?我从未在gcc预处理器中看到过这种情况,但我不能肯定地说没有预处理器可以实现这个功能。
What you could do however is run your script through something like sed to do your prepreprocessing so to speak before the preprocessor kicks in.
然而,你可以做的是通过像sed这样的东西运行你的脚本进行预处理,以便在预处理器启动之前说出来。
#3
Hmmm... I'm just guessing, but why don't you try something like this : :)
嗯......我只是猜测,但你为什么不尝试这样的东西::)
#define CATCH(varType,varName) catch(varType& varName) { /* some code here */ }