2014-10-22 5 views
2

У меня есть файл конфигурации в моем приложении, как показано ниже. Эта конфигурация должна быть выполнена до сборки программы.Итерация через #defines

#define NO_OF_COLORS 8 

#define COLOR_RESPONCE_1 'R' 
#define COLOR_RESPONCE_2 'G' 
#define COLOR_RESPONCE_3 'B' 
#define COLOR_RESPONCE_4 'M' 
#define COLOR_RESPONCE_5 'C' 
#define COLOR_RESPONCE_6 'Y' 
#define COLOR_RESPONCE_7 'O' 
#define COLOR_RESPONCE_8 'P' 

Внутри класса мне нужно добавить эти значения в std :: vector. Есть ли способ итерации через эти определяет. Может ли использовать макрос?

+0

Я не думаю, что вы можете повторить определение, поскольку оно является постоянным и не может быть подделано –

+2

Пожалуйста, может кто-нибудь сказать мне, почему некоторые программисты любят макросы –

+0

Также вы можете конвертировать между RGB и CMYK –

ответ

0

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

Лучше, если вы сделаете это так:

const char Colors[] = {'R','G','B','C','M','Y','O','P'}; 

, а затем использовать sizeof(Colors)/sizeof(Colors[0]), чтобы найти число элементов в этом массиве. Перебор с помощью цикла:

for(size_t index = 0; index < sizeof(Colors)/sizeof(Colors[0]); ++index) 
{} 

Или, если вы используете C++ 11 компилятор, который поддерживает диапазон на основе для петель, вы можете использовать:

for(char color : Colors) 
{ 
    // Use 'color' 
} 

Более просто:

for(auto color : Colors) 
{ 
    // Use 'color' 
} 
0

Кажется, что вы хотите перебрать нумерацию. C++ не поддерживает это (другие языки, такие как Java, по умолчанию имеют такое поведение. Чтобы обойти это, вы хотите создать структуру данных, которая является итерируемой, постоянной по длине и четко определенной, поэтому ее легко поддерживать.

Для, например, вы можете хранить данные в std::array (или до C++ 11 std::tr1::array)

const std::array<BYTE,8> Colors = { { 'R','G','B','C','M','Y','O','P' } }; 

std::array имеет итераторы, и оператор size(). Таким образом, вы можете сделать

for(std::array<BYTE,8>::const_iterator itr = Colors.begin(); 
    itr != Colors.end(); 
    ++itr) 
{ 
    // use (*itr) 
} 

или если вы хотите индекс

for(std::size_t index = 0 ; index < Colors.size() ; ++index) 
{ 
    // use Colors[i] 
} 

и c++11 вы можете использовать:

for(auto color : Colors) 
{ 
    // use color  
} 

Вы также можете скопировать их на std::vector по:

std::vector<BYTE> Colors_vector(Colors.begin(), Colors.end()); 
1

Почему не просто хранить эти в std::string, а не std::vector?

const std::string COLDATA = "RGBMCYOP"; 

Вы все еще можете получить доступ к нему, как std::vector с помощью индексации []:

COLDATA[3]; // == 'M' 

Или, если вы все еще хотите, чтобы положить, что в векторе можно сделать так:

const std::vector<char> COLDATAVEC(COLDATA.begin(), COLDATA.end()); 

Если вы используете C++ 11, вы можете поместить его в std::vector без использования std::string:

const std::vector<char> COLDATAVEC = {'R', 'G', 'B', 'M', 'C', 'Y', 'O', 'P'}; 
1

Вы можете использовать библиотеку Boost.Preprocessor. Он предоставляет макросы, имитирующие конструкции управления и структуры данных для препроцессора. Например. Вы можете перебирать свои цвета, как это:

#include <iostream> 
#include <boost/preprocessor.hpp> 

#define NO_OF_COLORS 8 

#define COLOR_RESPONCE_1 'R' 
#define COLOR_RESPONCE_2 'G' 
#define COLOR_RESPONCE_3 'B' 
#define COLOR_RESPONCE_4 'M' 
#define COLOR_RESPONCE_5 'C' 
#define COLOR_RESPONCE_6 'Y' 
#define COLOR_RESPONCE_7 'O' 
#define COLOR_RESPONCE_8 'P' 

#define PRINT_COLOR(z, x, _)     \ 
    std::cout << BOOST_PP_CAT(COLOR_RESPONCE_, x) << std::endl; 

int main() 
{ 
    BOOST_PP_REPEAT_FROM_TO(1, NO_OF_COLORS, PRINT_COLOR, 0); 
} 

BOOST_PP_REPEAT_FROM_TO имитирует цикл со счетчиком, PRINT_COLOR макрос реализует тело цикла.

Лично я бы использовал Boost.Preprocessor, только если у меня нет другого выбора. Он только имитирует конструкцию управления и имеет ряд ограничений (например, на нескольких итерациях цикла), а также отладка кода препроцессора не проще, чем тяжелый шаблон шаблона.

Заметка о стиле. Хотя препроцессор унаследован от C и необходим для отдельной (а также условной) компиляции, он чужд современным C++, на самом деле чуждый даже для pre-98 C++. Если вам нужны константы, которые вы можете и должны определить их сопзЬ, перечислений (или даже лучше с перечислений класса) или constexpr. Эти константы могут быть помещены в пространства имен, чтобы избежать столкновений имен, их можно гарантировать, что они будут инициализированы только один раз (extern const).

1

Определите свой переборе оборудование (ограничено 10 итераций):

#define ITER_0(MACRO, ACTION, DATA) 
#define ITER_1(MACRO, ACTION, DATA) ITER_0(MACRO, ACTION, DATA) ACTION(MACRO##1, DATA) 
#define ITER_2(MACRO, ACTION, DATA) ITER_1(MACRO, ACTION, DATA) ACTION(MACRO##2, DATA) 
#define ITER_3(MACRO, ACTION, DATA) ITER_2(MACRO, ACTION, DATA) ACTION(MACRO##3, DATA) 
#define ITER_4(MACRO, ACTION, DATA) ITER_3(MACRO, ACTION, DATA) ACTION(MACRO##4, DATA) 
#define ITER_5(MACRO, ACTION, DATA) ITER_4(MACRO, ACTION, DATA) ACTION(MACRO##5, DATA) 
#define ITER_6(MACRO, ACTION, DATA) ITER_5(MACRO, ACTION, DATA) ACTION(MACRO##6, DATA) 
#define ITER_7(MACRO, ACTION, DATA) ITER_6(MACRO, ACTION, DATA) ACTION(MACRO##7, DATA) 
#define ITER_8(MACRO, ACTION, DATA) ITER_7(MACRO, ACTION, DATA) ACTION(MACRO##8, DATA) 
#define ITER_9(MACRO, ACTION, DATA) ITER_8(MACRO, ACTION, DATA) ACTION(MACRO##9, DATA) 
#define ITER_10(MACRO, ACTION, DATA) ITER_9(MACRO, ACTION, DATA) ACTION(MACRO##10, DATA) 

#define ITER_I(ITERS, MACRO, ACTION, DATA) ITER_##ITERS(MACRO, ACTION, DATA) 
#define ITER(ITERS, MACRO, ACTION, DATA) ITER_I(ITERS, MACRO, ACTION, DATA) 

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

#define PRINT(MACRO, DATA) std::cout << MACRO; 
#define ADD_TO_VECTOR(MACRO, DATA) DATA.push_back(MACRO); 

Используйте эти действия, как показано ниже:

std::vector<char> v; 
ITER(NO_OF_COLORS, COLOR_RESPONCE_, ADD_TO_VECTOR, v) 

ITER(NO_OF_COLORS, COLOR_RESPONCE_, PRINT, ~) 

DEMO

Смежные вопросы