Фон
Списки инициализаторов C ++ 11 можно использовать для инициализации векторов и массивов с передачей аргументов конструкторам.
У меня есть фрагмент кода ниже, где я хотел бы инициализировать такой массив со всеми перечислениями eCOLORS
от eCOLORS::First
до eCOLORS::Last
с использованием списков инициализаторов.
Оригинальный код
Поскольку вся информация известна во время компиляции, я думаю, что есть способ решить эту проблему.
enum class eCOLORS
{
kBLUE=0, kGREEN, kRED, kPURPLE,
First=kBLUE, Last=kPURPLE
};
template< typename E >
size_t Size()
{
return (size_t)(E::Last) - (size_t)(E::First) + 1;
}
struct Foo
{
Foo( eCOLORS color ) { }
};
int main(int argc, char** argv)
{
Foo a[2] = {
{ eCOLORS::kRED },
{ eCOLORS::kGREEN }
}; // works, but requires manual maintenance if I add another color
/* how to feed v with all the enums from First to Last
without hard-coding?
Foo v[Size<eCOLORS>()] = {
};
*/
}
Гадкий псевдо-ответ
Похоже, консенсус заключается в том, что в настоящее время нет пути к этому.
Мое первоначальное намерение задать этот вопрос - я хочу автоматически
создать массив объектов Foo, инициализация которых основана исключительно на
перечисление eColors
. Я хотел не техническое решение, которое
будет работать, даже если вы добавите больше записей в eColors
.
Используя класс Enum из этого более раннего поста , я могу написать шаблон функции, который даст мне необходимую функциональность. Даже не используя этот класс Enum, вы все равно можете выполнить цикл от eCOLORS::First
до eCOLORS::Last
вместе с некоторыми уродливыми приведениями.
Мой уродливый псевдо-ответ - хитрый (нигде не такой хороший, как список инициализатора во время компиляции), но по крайней мере это нулевое обслуживание.
ПРИМЕЧАНИЕ: если появятся лучшие решения, я обновлю OP соответствующим образом.
template <typename T, typename E>
std::vector< T >
Initialize_With_Enums()
{
std::vector< T > v;
for( auto p : Enum<E>() )
v.push_back( T( p ));
return v;
}
int main( int argc, char** argv )
{
auto w = Initialize_With_Enum<Foo,eCOLORS>();
}