我的应用程序中有一个配置文件,如下所示。这个配置需要在构建程序之前完成。
#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)
您可以使用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 ++不同,实际上即使对于98之前的C ++也是如此。如果您需要常量,您可以并且应该使用 const ,枚举(或者使用枚举类更好)或 constexpr 。这些常量可以放在命名空间中以避免名称冲突,可以保证它们只能初始化一次( extern const )。
答案 1 :(得分:1)
你无法通过宏进行迭代。预处理器编译可能是多阶段的,但名称本身只能在第一遍(预处理)中解析。
如果你这样做会更好:
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)
{}
或者,如果您使用的是支持基于范围的for循环的C ++ 11编译器,您可以使用:
for(char color : Colors)
{
// Use 'color'
}
更简单:
for(auto color : Colors)
{
// Use 'color'
}
答案 2 :(得分: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'};
答案 3 :(得分: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, ~)
答案 4 :(得分: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() );