c++ - 嵌套 i, j 循环的宏

标签 c++ macros

如何编写可按如下方式使用的宏:

FOR(n)
    FOR(j, n)
        //do stuff

并且扩展为有效的嵌套 C++ for 循环,其中:

  • FOR(n)将使用名为 i 的循环变量(默认情况)并且不变量小于 ( < ) n ,
  • FOR(j, n)将使用名为第一个参数 ( j ) 且不变量小于 ( < ) n 的循环变量?

我看到一个有竞争力的程序员在编程 C++ 时使用了这种宏,但我自己无法编写这样的宏。

最佳答案

I'm aware it's bad practice to do things like this [...]

首先让我们再次强调这一点:是的,这是可怕的做法


现在,看起来像宏重载的实际上是宏调度,详细内容参见例如以下问答:

使用 the accepted answer 中的库代码:

#define CAT( A, B ) A ## B
#define SELECT( NAME, NUM ) CAT( NAME ## _, NUM )

#define GET_COUNT( _1, _2, _3, _4, _5, _6 /* ad nauseam */, COUNT, ... ) COUNT
#define VA_SIZE( ... ) GET_COUNT( __VA_ARGS__, 6, 5, 4, 3, 2, 1 )

#define VA_SELECT( NAME, ... ) SELECT( NAME, VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)

我们可以定义各种FOR_N重载,例如如下:

// Dispatch macro.
#define FOR( ... ) VA_SELECT( FOR, __VA_ARGS__ )

// Dispatch for 1 or 2 macro arguments for dispatch function.
#define FOR_1(N) for(int i = 0; i < N; ++i)
#define FOR_2(I, N) for(int I = 0; I < N; ++I)

使用方式如下:

int main() {
    int n = 3;
    FOR(n)
        FOR(j, n)
            std::cout << i << " " << j << "\n";
    /* 0 0
       0 1
       0 2
       1 0
       1 1
       1 2
       2 0
       2 1
       2 2 */
}

请注意,宏 for 循环的范围可能看起来像(帕斯卡尔式),但仅限于一行,因为它们扩展到

for(int i = 0; i < n; ++i)
    for(int j = 0; j < n; ++j)
        std::cout << i << " " << j << "\n";

而不是

for(int i = 0; i < n; ++i) {
    for(int j = 0; j < n; ++j) {
        std::cout << i << " " << j << "\n";
    }
}

要实现后者,您需要类似地显式添加 block 作用域:

FOR(n) {
    FOR(j, n) {
        std::cout << i << " " << j << "\n";
    }
}

关于c++ - 嵌套 i, j 循环的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64874358/

相关文章:

c++ - 我应该如何在 C++(在 ubuntu 上)中获取 "localhost"的完全限定域名?

c++ - operator+ 和 operator= 如何一起使用?

C++ 我是否错误地使用了 void 函数?

c - stdin 的 int 宏是什么?

c++ - 将核心转储从 Unix 生产环境移动到其他开发 Unix 环境

c++如何在没有默认构造函数的情况下定义另一种类型的对象成员

在导致错误时使用 do 定义的 C++ 宏

c++ - resource.h 中的宏有什么用?

macros - 使用宏在 Scheme 中柯里化(Currying)函数

c - 如何连接三个定义类型 : string + number + string?