我正在尝试做一些类似的事情:
custommacro x;它将扩展为:
declareSomething; int x; declareOtherthing;这有可能吗?
我已经用operator=欺骗过它一次,让它这样做,但它不能用声明完成。
发布于 2013-04-29 01:52:22
只要您愿意接受两个附加内容,您就可以省略括号:
例如:
#define LPAREN (
#define echo ECHO_MACRO LPAREN
#define done )
#define ECHO_MACRO(X) std::cout << (X) << "\n"
#define DSL(X) X
...
DSL(
echo "Look ma, no brains!" done;
)
...原因:
done宏,它将扩展为包含必要的关闭parenecho ... done表单看起来不像是对预处理器的宏调用,当预处理器进入它时,它没有被标记为扩展,我们是否放入括号是无关紧要的。因此,仅使用echo ... done将在文本中转储ECHO_MACRO调用DSL)包装整个块将导致在这次重新扫描传递时扩展对ECHO_MACRO的调用(DSL不会对结果做任何操作:它的存在只是为了强制重新扫描)( >d24echo >后面的展开中隐藏代码,因为否则宏主体中不匹配的圆括号将混淆preprocessor如果您想为这些命令创建一种完整的特定于域的语言,您还可以通过使核心命令更加笨拙来减少done命令的数量:
#define LPAREN (
#define begin NO_OP LPAREN 0
#define done );
#define echo ); ECHO_MACRO LPAREN
#define write ); WRITE_MACRO LPAREN
#define add ); ADD_MACRO LPAREN
#define sub ); SUB_MACRO LPAREN
#define NO_OP(X)
#define ECHO_MACRO(X) std::cout << (X) << "\n"
#define WRITE_MACRO(X) std::cout << (X)
#define ADD_MACRO(D, L, R) (D) = (L) + (R)
#define SUB_MACRO(D, L, R) (D) = (L) - (R)
#define DSL(X) DSL_2 X
#define DSL_2(X) X
int main(void) {
int a, b;
DSL((
begin
add a, 42, 47
sub b, 64, 50
write "a is: "
echo a
write "b is: "
echo b
done
))
return 0;
}在这种形式下,每个命令都预先设计为关闭前面的命令,因此只有最后一个命令需要一个done;您需要一个begin行,以便第一个要关闭的实际操作有一个open命令,否则两个括号将不匹配。
在C中处理这样的事情要比在C++中容易得多,因为C的预处理器更强大(它支持__VA_ARGS__,这对于复杂的宏元编程非常重要)。
哦对了,还有一件事-
...please从不在真正的代码中做到这一点。
发布于 2013-04-14 21:02:41
我知道你想做什么,但这是不可能的。宏只是一个文本替换,它不知道它后面会发生什么,所以尝试做custommacro x将扩展到custommacro是什么,一个空格,然后是x,这在语义上是不起作用的。
另外,关于你的echo黑客:在C++中使用运算符实际上非常简单:
#include <iostream>
#define echo std::cout <<
int main()
{
echo "Hello World!";
}但是你真的不应该写这样的代码(也就是,使用宏和伪回显hack)。你应该编写符合语言语法和你想要做的事情的语义的代码。如果您想写入标准输出,请使用std::cout。此外,如果您想使用echo,可以创建一个名为echo的函数,该函数在内部调用std::cout,但不要修改该语言的特性来创建您自己的特性。
发布于 2015-08-21 13:00:37
您可以使用for-loop和GnuC语句表达式扩展。
#define MY_MACRO\
FOR_MACRO(_uniq##__COUNTER__##name,{/*declareSomething*/ },{ /* declareOtherthing */ }) int
#define FOR_MACRO(NAME,FST_BLOCK,SND_BLOCK)\
for(int NAME = ({FST_BLOCK ;0;}); NAME<1 ; NAME++,(SND_BLOCK))这是“非常卫生的”,尽管这意味着无论您在这些代码块中做什么,都无法逃脱for-loop作用域的限制。
https://stackoverflow.com/questions/15993789
复制相似问题