我想创建一个宏,它将接受任意代码块作为其参数,例如
FOR_VECTOR( type, vect, code_block ) \
for( vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
code_block; \
}
问题是参数中的代码块,它可能包含任意数量的,
和 )
字符。
有什么好的解决办法吗?
有许多可能的解决方案。
如果您只需要一个表达式(而不是完整的代码块) - 您可以将其包含在(
和)
FOR_VECTOR( int, v, (func(i,1)) )
将起作用 -(func(i,1))
被视为单个宏参数
如果您的预处理器支持它们,另一个部分解决方案是可变参数宏。
您可以定义宏
#define COMMA ,
#define LPAR (
#define RPAR )
并使用它们来形成你的代码块 insted 的真实(
,
和)
FOR_VECTOR( int, v, func LPAR i COMMA 1 RPAR )
虽然它不是很可读。
或者您可以在宏替换后注释掉字符串文字的引号来做一个技巧:
FOR_VECTOR( type, vect, code_block ) \
for( vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
/code_block/; \
}
FOR_VECTOR( int, v, *"*/ func(i,1); proc(i,2); /*"* )
正如@mas.morozov 提到的,您可以使用可变参数宏:
#include <iostream>
#include <vector>
#define FOR_VECTOR( type, vect, ... ) \
for( std::vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
__VA_ARGS__ \
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6};
FOR_VECTOR(int, v, {
std::cout << *i << std::endl;
})
}
你可以在这里在线玩它:https ://godbolt.org/z/oLWV-z
我在这里找到了解决方案:https ://mort.coffee/home/obscure-c-features/
您还可以制作更通用的FOR_CONTAINER
宏:
#include <iostream>
#include <vector>
#define FOR_CONTAINER( container, ... ) \
for( decltype(container)::iterator i=container.begin(); i!=container.end(); ++i ) { \
__VA_ARGS__ \
}
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6};
FOR_CONTAINER(v, {
std::cout << *i << std::endl;
})
}