尝试使用预处理器生成X个不同的函数

时间:2016-06-14 09:27:53

标签: c++ c-preprocessor

所以我有一个类似#define NUM_FUNCTIONS 165的定义,我需要生成以下形式的165个函数:

void f0(){}
void f1(){}
void f2(){}
void f3(){}
// ...
void f164(){}

(0-164)或(1-165) - 无所谓

使用任何第三方都是不可能的(所以没有boost.preprocessor)。

我尝试使用cloakREPEAT宏(因为它只有100行)但它不适用于MSVC - 而且我还需要教它如何从165减少。 ..(它只能从9减少)

解决方案不一定是通用的和可重复使用的 - 我不在乎它有多乱 - 但是我需要X< 1000,它应该适用于过去15年的所有编译器。

最好应低于200-300行。

修改

嗯,我实际上需要转发声明它们并调用它们 - 而不是定义它们(我的坏......) - 我没有意识到在写这个问题时存在差异。

我真正的问题是我在静态库中有X个源文件,它们定义了X个不同的函数(每个源文件中有1个) - 在可执行文件中我需要创建一个调用(引用)所有虚拟函数的函数函数 - 这会强制所有.obj文件链接到可执行文件中(像google.test和doctest这样的库会遇到静态库的问题,因为它们的测试会自动注册)。

2 个答案:

答案 0 :(得分:0)

以下是我提出的建议:

#define DOCTEST_CONCAT_IMPL(s1, s2) s1##s2
#define DOCTEST_CONCAT(s1, s2) DOCTEST_CONCAT_IMPL(s1, s2)

#define DOCTEST_NUM_DUMMIES 243

int all() {
    int accum = 0;

#if defined(DOCTEST_NUM_DUMMIES)

#define DOCTEST_FWD_AND_CALL(x) int x(); accum += x();

#define DOCTEST_GEN_10(x) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 0))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 1))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 2))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 3))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 4))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 5))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 6))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 7))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 8))) \
    DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(x, 9)))

#define DOCTEST_GEN_100(x) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 0)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 1)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 2)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 3)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 4)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 5)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 6)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 7)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 8)) \
    DOCTEST_GEN_10(DOCTEST_CONCAT(x, 9))

#define DOCTEST_DIGIT_3 0
#define DOCTEST_DIGIT_2 0

#if DOCTEST_NUM_DUMMIES >= 100
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 1
DOCTEST_GEN_100(0)
#endif // 100
#if DOCTEST_NUM_DUMMIES >= 200
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 2
DOCTEST_GEN_100(1)
#endif // 200
#if DOCTEST_NUM_DUMMIES >= 300
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 3
DOCTEST_GEN_100(2)
#endif // 300
#if DOCTEST_NUM_DUMMIES >= 400
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 4
DOCTEST_GEN_100(3)
#endif // 400
#if DOCTEST_NUM_DUMMIES >= 500
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 5
DOCTEST_GEN_100(4)
#endif // 500
#if DOCTEST_NUM_DUMMIES >= 600
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 6
DOCTEST_GEN_100(5)
#endif // 600
#if DOCTEST_NUM_DUMMIES >= 700
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 7
DOCTEST_GEN_100(6)
#endif // 700
#if DOCTEST_NUM_DUMMIES >= 800
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 8
DOCTEST_GEN_100(7)
#endif // 800
#if DOCTEST_NUM_DUMMIES >= 900
#undef DOCTEST_DIGIT_3
#define DOCTEST_DIGIT_3 9
DOCTEST_GEN_100(8)
#endif // 900

#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 10
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 1
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 0))
#endif // 10
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 20
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 2
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 1))
#endif // 20
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 30
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 3
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 2))
#endif // 30
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 40
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 4
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 3))
#endif // 40
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 50
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 5
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 4))
#endif // 50
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 60
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 6
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 5))
#endif // 60
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 70
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 7
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 6))
#endif // 70
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 80
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 8
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 7))
#endif // 80
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 >= 90
#undef DOCTEST_DIGIT_2
#define DOCTEST_DIGIT_2 9
DOCTEST_GEN_10(DOCTEST_CONCAT(DOCTEST_DIGIT_3, 8))
#endif // 90

#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 1
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 0)))
#endif // 0
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 2
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 1)))
#endif // 1
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 3
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 2)))
#endif // 2
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 4
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 3)))
#endif // 3
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 5
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 4)))
#endif // 4
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 6
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 5)))
#endif // 5
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 7
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 6)))
#endif // 6
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 8
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 7)))
#endif // 7
#if DOCTEST_NUM_DUMMIES - DOCTEST_DIGIT_3 * 100 - DOCTEST_DIGIT_2 * 10 >= 9
DOCTEST_FWD_AND_CALL(DOCTEST_CONCAT(dummy, DOCTEST_CONCAT(DOCTEST_CONCAT(DOCTEST_DIGIT_3, DOCTEST_DIGIT_2), 8)))
#endif // 8

#endif // DOCTEST_NUM_DUMMIES

    return accum;
}

int main() {

    return 0;
}

现在将向前声明并调用所有243个函数 - 正是我想要的。

适用于边缘情况 - 当数字为0 / 1/9/10/99/100/109/990/999/1000 +(1000或更多时,它调用999而不再更新 - 不会出错)

预处理器的当前输出是:

# 1 "b.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "b.cpp"





int all() {
    int accum = 0;
# 43 "b.cpp"
int dummy000(); accum += dummy000(); int dummy001(); accum += dummy001(); int dummy002(); accum += dummy002(); int dummy003(); accum += dummy003(); int dummy004(); accum += dummy004(); int dummy005(); accum += dummy005(); int dummy006(); accum += dummy006(); int dummy007(); accum += dummy007(); int dummy008(); accum += dummy008(); int dummy009(); accum += dummy009(); int dummy010(); accum += dummy010(); int dummy011(); accum += dummy011(); int dummy012(); accum += dummy012(); int dummy013(); accum += dummy013(); int dummy014(); accum += dummy014(); int dummy015(); accum += dummy015(); int dummy016(); accum += dummy016(); int dummy017(); accum += dummy017(); int dummy018(); accum += dummy018(); int dummy019(); accum += dummy019(); int dummy020(); accum += dummy020(); int dummy021(); accum += dummy021(); int dummy022(); accum += dummy022(); int dummy023(); accum += dummy023(); int dummy024(); accum += dummy024(); int dummy025(); accum += dummy025(); int dummy026(); accum += dummy026(); int dummy027(); accum += dummy027(); int dummy028(); accum += dummy028(); int dummy029(); accum += dummy029(); int dummy030(); accum += dummy030(); int dummy031(); accum += dummy031(); int dummy032(); accum += dummy032(); int dummy033(); accum += dummy033(); int dummy034(); accum += dummy034(); int dummy035(); accum += dummy035(); int dummy036(); accum += dummy036(); int dummy037(); accum += dummy037(); int dummy038(); accum += dummy038(); int dummy039(); accum += dummy039(); int dummy040(); accum += dummy040(); int dummy041(); accum += dummy041(); int dummy042(); accum += dummy042(); int dummy043(); accum += dummy043(); int dummy044(); accum += dummy044(); int dummy045(); accum += dummy045(); int dummy046(); accum += dummy046(); int dummy047(); accum += dummy047(); int dummy048(); accum += dummy048(); int dummy049(); accum += dummy049(); int dummy050(); accum += dummy050(); int dummy051(); accum += dummy051(); int dummy052(); accum += dummy052(); int dummy053(); accum += dummy053(); int dummy054(); accum += dummy054(); int dummy055(); accum += dummy055(); int dummy056(); accum += dummy056(); int dummy057(); accum += dummy057(); int dummy058(); accum += dummy058(); int dummy059(); accum += dummy059(); int dummy060(); accum += dummy060(); int dummy061(); accum += dummy061(); int dummy062(); accum += dummy062(); int dummy063(); accum += dummy063(); int dummy064(); accum += dummy064(); int dummy065(); accum += dummy065(); int dummy066(); accum += dummy066(); int dummy067(); accum += dummy067(); int dummy068(); accum += dummy068(); int dummy069(); accum += dummy069(); int dummy070(); accum += dummy070(); int dummy071(); accum += dummy071(); int dummy072(); accum += dummy072(); int dummy073(); accum += dummy073(); int dummy074(); accum += dummy074(); int dummy075(); accum += dummy075(); int dummy076(); accum += dummy076(); int dummy077(); accum += dummy077(); int dummy078(); accum += dummy078(); int dummy079(); accum += dummy079(); int dummy080(); accum += dummy080(); int dummy081(); accum += dummy081(); int dummy082(); accum += dummy082(); int dummy083(); accum += dummy083(); int dummy084(); accum += dummy084(); int dummy085(); accum += dummy085(); int dummy086(); accum += dummy086(); int dummy087(); accum += dummy087(); int dummy088(); accum += dummy088(); int dummy089(); accum += dummy089(); int dummy090(); accum += dummy090(); int dummy091(); accum += dummy091(); int dummy092(); accum += dummy092(); int dummy093(); accum += dummy093(); int dummy094(); accum += dummy094(); int dummy095(); accum += dummy095(); int dummy096(); accum += dummy096(); int dummy097(); accum += dummy097(); int dummy098(); accum += dummy098(); int dummy099(); accum += dummy099();




int dummy100(); accum += dummy100(); int dummy101(); accum += dummy101(); int dummy102(); accum += dummy102(); int dummy103(); accum += dummy103(); int dummy104(); accum += dummy104(); int dummy105(); accum += dummy105(); int dummy106(); accum += dummy106(); int dummy107(); accum += dummy107(); int dummy108(); accum += dummy108(); int dummy109(); accum += dummy109(); int dummy110(); accum += dummy110(); int dummy111(); accum += dummy111(); int dummy112(); accum += dummy112(); int dummy113(); accum += dummy113(); int dummy114(); accum += dummy114(); int dummy115(); accum += dummy115(); int dummy116(); accum += dummy116(); int dummy117(); accum += dummy117(); int dummy118(); accum += dummy118(); int dummy119(); accum += dummy119(); int dummy120(); accum += dummy120(); int dummy121(); accum += dummy121(); int dummy122(); accum += dummy122(); int dummy123(); accum += dummy123(); int dummy124(); accum += dummy124(); int dummy125(); accum += dummy125(); int dummy126(); accum += dummy126(); int dummy127(); accum += dummy127(); int dummy128(); accum += dummy128(); int dummy129(); accum += dummy129(); int dummy130(); accum += dummy130(); int dummy131(); accum += dummy131(); int dummy132(); accum += dummy132(); int dummy133(); accum += dummy133(); int dummy134(); accum += dummy134(); int dummy135(); accum += dummy135(); int dummy136(); accum += dummy136(); int dummy137(); accum += dummy137(); int dummy138(); accum += dummy138(); int dummy139(); accum += dummy139(); int dummy140(); accum += dummy140(); int dummy141(); accum += dummy141(); int dummy142(); accum += dummy142(); int dummy143(); accum += dummy143(); int dummy144(); accum += dummy144(); int dummy145(); accum += dummy145(); int dummy146(); accum += dummy146(); int dummy147(); accum += dummy147(); int dummy148(); accum += dummy148(); int dummy149(); accum += dummy149(); int dummy150(); accum += dummy150(); int dummy151(); accum += dummy151(); int dummy152(); accum += dummy152(); int dummy153(); accum += dummy153(); int dummy154(); accum += dummy154(); int dummy155(); accum += dummy155(); int dummy156(); accum += dummy156(); int dummy157(); accum += dummy157(); int dummy158(); accum += dummy158(); int dummy159(); accum += dummy159(); int dummy160(); accum += dummy160(); int dummy161(); accum += dummy161(); int dummy162(); accum += dummy162(); int dummy163(); accum += dummy163(); int dummy164(); accum += dummy164(); int dummy165(); accum += dummy165(); int dummy166(); accum += dummy166(); int dummy167(); accum += dummy167(); int dummy168(); accum += dummy168(); int dummy169(); accum += dummy169(); int dummy170(); accum += dummy170(); int dummy171(); accum += dummy171(); int dummy172(); accum += dummy172(); int dummy173(); accum += dummy173(); int dummy174(); accum += dummy174(); int dummy175(); accum += dummy175(); int dummy176(); accum += dummy176(); int dummy177(); accum += dummy177(); int dummy178(); accum += dummy178(); int dummy179(); accum += dummy179(); int dummy180(); accum += dummy180(); int dummy181(); accum += dummy181(); int dummy182(); accum += dummy182(); int dummy183(); accum += dummy183(); int dummy184(); accum += dummy184(); int dummy185(); accum += dummy185(); int dummy186(); accum += dummy186(); int dummy187(); accum += dummy187(); int dummy188(); accum += dummy188(); int dummy189(); accum += dummy189(); int dummy190(); accum += dummy190(); int dummy191(); accum += dummy191(); int dummy192(); accum += dummy192(); int dummy193(); accum += dummy193(); int dummy194(); accum += dummy194(); int dummy195(); accum += dummy195(); int dummy196(); accum += dummy196(); int dummy197(); accum += dummy197(); int dummy198(); accum += dummy198(); int dummy199(); accum += dummy199();
# 89 "b.cpp"
int dummy200(); accum += dummy200(); int dummy201(); accum += dummy201(); int dummy202(); accum += dummy202(); int dummy203(); accum += dummy203(); int dummy204(); accum += dummy204(); int dummy205(); accum += dummy205(); int dummy206(); accum += dummy206(); int dummy207(); accum += dummy207(); int dummy208(); accum += dummy208(); int dummy209(); accum += dummy209();




int dummy210(); accum += dummy210(); int dummy211(); accum += dummy211(); int dummy212(); accum += dummy212(); int dummy213(); accum += dummy213(); int dummy214(); accum += dummy214(); int dummy215(); accum += dummy215(); int dummy216(); accum += dummy216(); int dummy217(); accum += dummy217(); int dummy218(); accum += dummy218(); int dummy219(); accum += dummy219();




int dummy220(); accum += dummy220(); int dummy221(); accum += dummy221(); int dummy222(); accum += dummy222(); int dummy223(); accum += dummy223(); int dummy224(); accum += dummy224(); int dummy225(); accum += dummy225(); int dummy226(); accum += dummy226(); int dummy227(); accum += dummy227(); int dummy228(); accum += dummy228(); int dummy229(); accum += dummy229();




int dummy230(); accum += dummy230(); int dummy231(); accum += dummy231(); int dummy232(); accum += dummy232(); int dummy233(); accum += dummy233(); int dummy234(); accum += dummy234(); int dummy235(); accum += dummy235(); int dummy236(); accum += dummy236(); int dummy237(); accum += dummy237(); int dummy238(); accum += dummy238(); int dummy239(); accum += dummy239();
# 133 "b.cpp"
int dummy240(); accum += dummy240();


int dummy241(); accum += dummy241();


int dummy242(); accum += dummy242();
# 162 "b.cpp"
    return accum;
}

int main() {

    return 0;
}

答案 1 :(得分:0)

对于通用foreach:http://saadahmad.ca/cc-preprocessor-metaprogramming-2/ 这正是您所需要的,尽管它远远超过200-300字节。不过,值得一读。 但是,如果你只想生成上述函数,我只想说:

#include <iostream>
using namespace std;

#define _CAT( x, y )            x ## y
#define CAT( x, y )             _CAT( x, y )
#define REPEATER()              REPEAT4 ( ,                         ) REPEAT4 ( 1,                0 )

// repeat these two lines as many times as you wish
#define REPEAT4( digits, zero ) REPEAT3 ( CAT( digits, zero ), zero ) REPEAT3 ( CAT( digits, 1 ), 0 )
#define REPEAT3( digits, zero ) REPEAT2 ( CAT( digits, zero ), zero ) REPEAT2 ( CAT( digits, 1 ), 0 )

#define REPEAT2( digits, zero ) REPEAT1 ( CAT( digits, zero )       ) REPEAT1 ( CAT( digits, 1 )    )
#define REPEAT1( digits )       REPEATED( CAT( digits, 0    )       ) REPEATED( CAT( digits, 1 )    )

#define REPEATED( i ) void CAT(f, i) () {}

REPEATER()

int main() {
    f0();
    f101();
    return 0;
}

这是二进制编号。如果您确定需要或需要十进制编号,请随意为每个宏添加8个调用:)。您只需要复制第二列并将1更改为列号。

提示:使用gcc -E file.cpp验证预处理器输出