C ++ 11有趣的初始化列表,数组和枚举 [英] C++11 Fun with initializer lists, arrays, and enumerations
问题描述
C ++ 11初始化程序列表可用于将向量和数组初始化为参数传递给构造函数。
C++11 initializer lists can be used to initialize vectors and arrays with argument passing to constructors.
下面有一段代码,我想用 eCOLORS中的所有
转换为 eCOLORS
枚举来初始化这样一个数组::首先使用初始化列表将 eCOLORS :: Last
。
I have a piece of code below where I would like to initialize such an array with all the enumerations of eCOLORS
from eCOLORS::First
to eCOLORS::Last
using initializer lists.
由于所有信息在编译时都是已知的,所以我认为有办法解决此问题。
Since all information is known at compile time, I think there is a way to solve this problem.
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
中添加更多条目后,
仍然可以工作。
My original intent in asking this question is, I want to automagically create an array of Foo objects whose initialization is solely based on the enumeration of
eColors
. I wanted a no maintenance solution that would work even after you add more entries intoeColors
.
使用中的Enum类,我可以编写一个功能模板,为我提供所需的功能。即使不使用该Enum类,您仍然可以从 eCOLORS :: First
循环到 eCOLORS :: Last
Using the Enum class from this earlier post, I can write a function template that gives me the functionality that I need. Even without using that Enum class, you could still loop from eCOLORS::First
to eCOLORS::Last
, along with some ugly casts.
我的丑陋的伪答案是kludgy(没有编译时初始化列表那么好),但至少它是零维护。
My ugly pseudo-answer is kludgy (nowhere as nice as a compile-time initializer list), but at least it is zero maintenance.
注意:如果有更好的解决方案,我将相应地更新操作程序。
NOTE: if better solutions come up, I will update the OP accordingly.
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>();
}
推荐答案
您可以使用可变参数来做到这一点模板以及我称之为索引技巧的东西。
You can do this with variadic templates and what I'm going to call the "indices trick".
typedef std::underlying_type<eCOLORS>::type underlying;
// just a type to carry around variadic pack of numbers
template <underlying...> struct indices {};
// A template to build up a pack of Count numbers from first
// third parameter is an accumulator
template <underlying First, underlying Count, typename Acc = indices<>>
struct make_indices;
// base case
template <underlying X, underlying... Acc>
struct make_indices<X, 0, indices<Acc...>> { typedef indices<Acc...> type; };
// recursive build up of the pack
template <underlying First, underlying Count, underlying... Acc>
struct make_indices<First, Count, indices<Acc...>>
: make_indices<First, Count-1, indices<First+Count-1, Acc...>> {};
size_t const max_colors = underlying(eCOLORS::Last) - underlying(eCOLORS::First)+1;
// shortcut
typedef make_indices<
underlying(eCOLORS::First),
max_colors
>::type all_eCOLORS_indices;
// takes a dummy parameter with the pack we built
template <underlying... Indices>
std::array<eCOLORS, max_colors> const& all_colors(indices<Indices...>) {
// convert each number to the enum and stick it in an static array
static std::array<eCOLORS, max_colors> const all = {
eCOLORS(Indices)...
};
return all;
}
std::array<eCOLORS, max_colors> const& all_colors() {
// create a dummy object of the indices pack type and pass it
return all_colors(all_eCOLORS_indices());
}
这假定所有枚举数都是顺序的,并且需要 std :: underlying_type
在GCC 4.6中不受支持(将在4.7中使用,但是您可以在某种程度上对其进行模仿)。
This assumes all the enumerators are sequential, and needs std::underlying_type
which is not supported in GCC 4.6 (will be in 4.7, but you can emulate it to a certain extent).
这篇关于C ++ 11有趣的初始化列表,数组和枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!