Как сократить эти строки с помощью препроцессора? - PullRequest
1 голос
/ 16 апреля 2019

У меня есть эти строки в моем коде, и я подумал, что может быть какой-то хороший способ использовать препроцессор для генерации этих строк (от 0 до 31).

    Mem_type MEM_0[MAX_NUM_MEM];
    Mem_type MEM_1[MAX_NUM_MEM];
    Mem_type MEM_2[MAX_NUM_MEM];
    Mem_type MEM_3[MAX_NUM_MEM];
    Mem_type MEM_4[MAX_NUM_MEM];
    Mem_type MEM_5[MAX_NUM_MEM];
    ...
    Mem_type MEM_30[MAX_NUM_MEM];
    Mem_type MEM_31[MAX_NUM_MEM];

    Mem_type *MEM[NUM_BANKS];

    MEM[0] = MEM_0;
    MEM[1] = MEM_1;
    MEM[2] = MEM_2;
    MEM[3] = MEM_3;
    MEM[4] = MEM_4;
    MEM[5] = MEM_5;
    ...
    MEM[30] = MEM_30;
    MEM[31] = MEM_31;

Например, что-то вроде:

    #define Gen(n) MEM[n] = MEM_n
    #for (k=0; k<32; k++) Gen(k);

(Причина, по которой я не делаю, как показано ниже, заключается в том, что я обнаружил, что у моей машины есть некоторый максимальный непрерывный предел размера массива, поэтому я попытался разбить его на отдельные массивы, чтобы у меня был больший агрегированный размер MEM.)

    Mem_type MEM[NUM_BANKS][MAX_NUM_MEM];

Ответы [ 5 ]

3 голосов
/ 16 апреля 2019

Использование boost / препроцессора / повторения / repeat.hpp:

#include <boost/preprocessor/repetition/repeat.hpp>
class Mem_type {};

#define MAX_NUM_MEM  5
#define NUM_BANKS    5

#define MEM_DECL(z, n, text)  Mem_type MEM_## n[MAX_NUM_MEM];
#define MEM_MEMB(z, n, text)  MEM_## n,

// expands to `Mem_type MEM_?[MAX_NUM_MEM];`
BOOST_PP_REPEAT(NUM_BANKS, MEM_DECL, ())

Mem_type *MEM[NUM_BANKS] = {
    // expands to `MEM_?,`
    BOOST_PP_REPEAT(NUM_BANKS, MEM_MEMB, ())
};
3 голосов
/ 16 апреля 2019

В сети есть статьи о символьных вычислениях на стадии предварительной обработки, типичным примером будет http://jhnet.co.uk/articles/cpp_magic

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

#define ONE_MEM(i, a) MemType mem_ ## a[MAX_MEM]; mem[i] = mem_ ## a
#define MEM_1(i, a) ONE_MEM(i, a); ONE_MEM(i + 1, a ## 1)
#define MEM_2(i, a) MEM_1(i, a); MEM_1(i + 2, a##2)
#define MEM_4(i, a) MEM_2(i, a); MEM_2(i + 4, a##4)

и т. д., теперь это логарифмическое количество заданных макросов.

(еще не проверялфактическому определению может потребоваться косвенное косвенное указание или два.)

Могут быть улучшения, например, объявление макропараметра вместо mem и т. д.

2 голосов
/ 16 апреля 2019

Стек очень ограничен и не должен использоваться для выделения огромных структур данных, как это описано выше здесь . Вместо этого попробуйте выделить вашу память, используя new[]. Если вам нужны многомерные массивы, вы можете использовать массив указателей, которые указывают на массивы, указывающие на ваши структуры, как описано здесь .

Однако, поскольку ваше первоначальное намерение состояло в том, чтобы иметь один массив, это должно сработать без необходимости препроцессора:

Mem_type* MEM = new Mem_type[MAX_NUM_MEM]; // MAX_NUM_MEM is multiplied by NUM_BANKS here
// do things [...]
delete[] MEM;
MEM = nullptr;

Было бы неплохо обернуть это в класс, выделить в конструкторе, вызвать исключение в случае сбоя выделения и освободить в деструкторе.

1 голос
/ 16 апреля 2019

Вы можете использовать X Macro вместе с конкатенацией токенов

#define LIST_OF_MEMS    \
X(0)                    \   
X(1)                    \
X(2)                    \
X(3)                    \
X(4)                    \
X(5)                    \
...                     \
X(30)                   \
X(31)                   \

Теперь вы можете использовать его каждый раз, когда захотите что-нибудь сделать со всеми MEM.Обратите внимание, что использование всех заглавных букв для имени переменной - плохая идея

// declaration
#define X(num) Mem_type mem_##num[MAX_NUM_MEM];
LIST_OF_MEMS
#undef X

// assignment
#define X(num) MEM[num] = mem_##num;
LIST_OF_MEMS
#undef X
1 голос
/ 16 апреля 2019

Использование динамического распределения с векторами STL:

#include <vector>

class Mem_type {};
const int MAX_NUM_MEM = 5;
const int NUM_BANKS   = 5;

// allocates NUM_BANKS vectors with MAX_NUM_MEM objects of Mem_type
std::vector<std::vector<Mem_type>> MEM(NUM_BANKS, std::vector<Mem_type>(MAX_NUM_MEM));
...