是否可以将宏的参数视为正则表达式?

时间:2022-06-21 22:32:02

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 */ }