Variadic рекурсивные макросы препроцессора - действительно ли это возможно?

Вам нужно преобразовать year в строку перед конкатенацией.

year = 2019
tariq1 = str(year)+'-01-01'
tariq2 = str(year)+'-12-31'
while year > 2015:
    for stock in string:
        max=quandl.get(stock, start_date=tariq1, end_date=tariq2)
        max
    year = year - 1

Кроме того, вы, вероятно, также хотите обновить значения tariq1 и tariq2 внутри цикла, а не до него:

year = 2019
while year > 2015:
    tariq1 = str(year)+'-01-01'
    tariq2 = str(year)+'-12-31'
    for stock in string:
        max=quandl.get(stock, start_date=tariq1, end_date=tariq2)
        max
    year = year - 1
39
задан Brian Tompsett - 汤莱恩 5 February 2016 в 09:58
поделиться

4 ответа

Нет, потому что препроцессор делает только один «удар» по файлу. Невозможно заставить его рекурсивно определять макросы.

Единственный код, который я видел, делал что-то вроде этого, это , а не variadic, но использовал значения по умолчанию, которые пользователь должен был передать:

x = MAX_OF_8 (a, b, -1, -1, -1, -1, -1, -1)

, предполагая все значения были неотрицательными.

Встроенные функции должны дать вам то же самое для C ++, по крайней мере. Как вы утверждаете, вероятно, лучше оставить функцию с переменными аргументами, подобными printf () .

12
ответ дан 27 November 2019 в 02:32
поделиться

Если вы идете по этому пути в C ++, взгляните на шаблонное метапрограммирование . Это не красиво, и это может не решить вашу проблему, но она справится с рекурсией.

5
ответ дан 27 November 2019 в 02:32
поделиться

Вы можете рассмотреть этот обман, так как он не является рекурсивным и не выполняет работу в препроцессор. И он использует расширение GCC. И это работает только для одного типа. Однако это макрокомандный макрос MAX_OF_N:

#include <iostream>
#include <algorithm>

#define MAX_OF_N(...) ({\
        int ra[] = { __VA_ARGS__ }; \
        *std::max_element(&ra[0], &ra[sizeof(ra)/sizeof(int)]); \
    })

int main() {
    int i = 12;
    std::cout << MAX_OF_N(1,3,i,6);
}

Да, и из-за выражения потенциальной переменной в списке инициализатора я не думаю, что это эквивалентно (использование собственной функции, чтобы избежать std :: max_element) будет работать в C89. Но я' Я не уверен, что в C89 также есть переменные макросы.

Вот кое-что, что, я думаю, обходит ограничение «только один тип». Это становится немного волосатым, хотя:

#include <iostream>
#include <algorithm>

#define MAX_OF_N(x, ...) ({\
        typeof(x) ra[] = { (x), __VA_ARGS__ }; \
        *std::max_element(&ra[0], &ra[sizeof(ra)/sizeof(ra[0])]); \
    })

int main() {
    int i = 12;
    std::cout << MAX_OF_N(i+1,1,3,6,i);
}
10
ответ дан 27 November 2019 в 02:32
поделиться

Я думаю, что даже если бы вы могли расширять макросы рекурсивно, у вашего подхода была бы одна небольшая проблема с точки зрения эффективности ... когда макросы раскрываются, если MAX_OF_ [N-1] больше, то вам придется снова оценить его с нуля.

Вот глупый и глупый ответ, который, вероятно, никому не понравится xD

файл "source.c"

#include "my_macros.h"
...

файл "Makefile"

myprogram: source.c my_macros.h
 gcc source.c -o myprogram

my_macros.h: make_macros.py
 python make_macros.py > my_macros.h

файл "make_macros.py"

def split(l):
    n = len(l)
    return l[:n/2], l[n/2:]

def gen_param_seq(n):
    return [chr(i + ord("A")) for i in range(n)]

def make_max(a, b):
    if len(a) == 1:
        parta = "("+a[0]+")"
    else:
        parta = make_max(*split(a))

    if len(b) == 1:
        partb = "("+b[0]+")"
    else:
        partb = make_max(*split(b))

    return "("+parta +">"+partb+"?"+parta+":"+partb+")"

for i in range(2, 9):
    p = gen_param_seq(i)
    print "#define MAX_"+str(i)+"("+", ".join(p)+") "+make_max(*split(p))

тогда выЯ определю эти красивые макросы:

#define MAX_2(A, B) ((A)>(B)?(A):(B))
#define MAX_3(A, B, C) ((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))
#define MAX_4(A, B, C, D) (((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D)))
#define MAX_5(A, B, C, D, E) (((A)>(B)?(A):(B))>((C)>((D)>(E)?(D):(E))?(C):((D)>(E)?(D):(E)))?((A)>(B)?(A):(B)):((C)>((D)>(E)?(D):(E))?(C):((D)>(E)?(D):(E))))
#define MAX_6(A, B, C, D, E, F) (((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))>((D)>((E)>(F)?(E):(F))?(D):((E)>(F)?(E):(F)))?((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))):((D)>((E)>(F)?(E):(F))?(D):((E)>(F)?(E):(F))))
#define MAX_7(A, B, C, D, E, F, G) (((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))>(((D)>(E)?(D):(E))>((F)>(G)?(F):(G))?((D)>(E)?(D):(E)):((F)>(G)?(F):(G)))?((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))):(((D)>(E)?(D):(E))>((F)>(G)?(F):(G))?((D)>(E)?(D):(E)):((F)>(G)?(F):(G))))
#define MAX_8(A, B, C, D, E, F, G, H) ((((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D)))>(((E)>(F)?(E):(F))>((G)>(H)?(G):(H))?((E)>(F)?(E):(F)):((G)>(H)?(G):(H)))?(((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D))):(((E)>(F)?(E):(F))>((G)>(H)?(G):(H))?((E)>(F)?(E):(F)):((G)>(H)?(G):(H))))

и самое лучшее в нем то, что ... он работает ^ _ ^

7
ответ дан 27 November 2019 в 02:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: