技巧:使用宏填充数组值(代码生成)

Naw*_*waz 11 c c++ arrays macros

C++模板是伪装的宏吗?

我正在阅读上面的主题,突然想到了这个想法:为什么不尝试编写一些可以在我们的真实代码中使用的棘手的宏(不只是作为在现实生活中无用的谜题)?

所以首先想到的是:用宏填充数组值:

int f(int &i) { return ++i; }

#define e100     r5(m20)
#define m20      m5,m5,m5,m5
#define m5       r5(e1)
#define e1       f(i)  //avoiding ++i right here, to avoid UB!
#define r5(e)    e,e,e,e,e

int main() {
        int i=0;           //this is used in the macro e1
        int a[] = {e100};  //filling array values with macros!
        int n  = sizeof(a)/sizeof(int);
        cout << "count = " << n << endl;
        for(int i = 0 ; i < n ; i++ ) 
            cout << a[i] << endl;
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

count = 100
1
2
3
4
.
.
.
100
Run Code Online (Sandbox Code Playgroud)

在线演示:http://www.ideone.com/nUYrq

我们可以在紧凑性或通用性(可能两者)方面进一步改进这个解决方案吗?我们可以摆脱i宏中需要的变量吗?还是其他任何改进?

我还想知道这是否是C++和C中的有效代码(当然忽略了打印部分)?

编辑:

我意识到调用的顺序f()似乎仍未明确.我不确定,因为我认为数组初始化中的逗号与逗号运算符(通常)一样.但如果是的话,我们可以避免它吗?标准的哪一部分说明未指明

Jen*_*edt 5

P99有一个完全符合你想要的宏

#include "p99_map.h"

int Ara[] = { P99_POSS(100) };
Run Code Online (Sandbox Code Playgroud)

它的优点是它完全是编译时间,没有功能等的动态初始化.

对于您来说,它可能具有使用C99功能的缺点,特别是具有可变长度参数的宏.


Mat*_* M. 5

如果您希望深入研究预处理器编程,我只能推荐Boost.Preprocessor库作为构建块,您将避免从头开始重写.

例如,为了创建你的表,我会使用(ideone):

#include <iostream>

#include <boost/preprocessor/repetition/enum.hpp>

#define ORDER(z, n, text) n

int main() {
  int const a[] = { BOOST_PP_ENUM(100, ORDER, ~) };
  std::size_t const n = sizeof(a)/sizeof(int);

  std::cout << "count = " << n << "\n";

  for(std::size_t i = 0 ; i != n ; ++i ) 
    std::cout << a[i] << "\n";

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

并把所有的东西留给Boost :)

注意:此枚举从0到99,而不是1到100,还有其他操作可用于执行算术;)

编辑:这是如何工作的?

首先,我只推荐BOOST_PP_ENUM的doc条目

BOOST_PP_ENUM 是一个带有3个参数的宏: (n, MACRO, data)

  • n:一个整数
  • MACRO:一个接受3个参数的宏: (z, i, data)
  • data:一些数据,方便您传递给 macro

然后MACRO它将由逗号分隔的n次连续调用替换:

MACRO(z, 0, data), MACRO(z, 1, data), ... , MACRO(z, n-1, data)
Run Code Online (Sandbox Code Playgroud)

你可以随心所欲地做任何事情MACRO.

我担心我从未使用过这个z论点,它是在内部使用的,理论上你可以用它来加速这个过程.