如何将任意代码块作为参数传递给C宏

use*_*454 11 c++ macros comma

我想创建一个宏,它将接受任意代码块作为其参数

FOR_VECTOR( type, vect, code_block ) \
  for( vector<type>::iterator i=vect.begin(); i!=vect.end(); ++i ) { \
    code_block; \
  }
Run Code Online (Sandbox Code Playgroud)

问题是在参数的代码块,其可以包含的任意数量,)字符.

有什么好的解决方案吗?

mas*_*zov 9

有许多可能的解决方案.

如果你只需要一个表达式(不是一个完整的代码块) - 你可以将它包含在(和中)

FOR_VECTOR( int, v, (func(i,1)) )
Run Code Online (Sandbox Code Playgroud)

将工作 - (func(i,1))被视为单个宏参数

另一个部分解决方案是可变参数宏,如果您的预处理器支持它们.

您可以定义宏

#define COMMA ,
#define LPAR (
#define RPAR )
Run Code Online (Sandbox Code Playgroud)

并使用它们来形成你真正的( ,)

FOR_VECTOR( int, v, func LPAR i COMMA 1 RPAR )
Run Code Online (Sandbox Code Playgroud)

但它不是很易读.

或者你可以通过在宏替换后注释掉字符串文字的引号来做一个技巧:

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); /*"* )
Run Code Online (Sandbox Code Playgroud)

  • 我为那些需要维护代码的人而哭泣.:) (9认同)

Mic*_*pso 5

正如@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;
    })
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里在线玩它: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;
    })
}
Run Code Online (Sandbox Code Playgroud)

在这里试试:https : //godbolt.org/z/9Gzqja