是否可以从枚举创建initializer_list



是否可以用枚举中的元素声明静态initializer_list,而不显式声明它,以便将其用作默认参数?示例:

#include <initializer_list>   
#include <iostream>
enum ID {
A,
B,
C,
D
};

inline constexpr std::initializer_list< ID > all { A, B, C, D };
void func(const std::initializer_list< ID >& args = all) {
for (const auto& arg : args) {
std::cout << arg << std::endl;
}
}
int main(int argc, char const *argv[]) {
/* code */
func();  // prints 'all' contents
return 0;
}

但是,我希望避免在两个位置显式声明ID列表。我知道我可以为此使用std::vector

#include <initializer_list>   
#include <iostream>
#include <vector>
enum ID {
A,
B,
C,
D,
// ...
MAX = D
};

inline std::vector< ID > all() {
std::vector< ID > list(ID::MAX + 1);
for (int i = ID::A; i <= ID::MAX; i++) {
list[i] = static_cast< ID >(i);
}
return list;
}

void func(const std::vector< ID >& args = all()) {
for (const auto& arg : args) {
std::cout << arg << std::endl;
}
}

int main(int argc, char const *argv[]) {
/* code */
func();
return 0;
}

但我很好奇是否可以用CCD_ 3来实现这一点。

enum IDs {
A,
B,
C,
D,
ENUM_COUNT,
};
template<class E>
using enum_indexes_t = std::make_index_sequence<static_cast<std::size_t>( E::ENUM_COUNT )>;
template<class E>
constexpr enum_indexes_t<E> enum_indexes_v = {};
template<class E, std::size_t...Is>
constexpr auto enum_list( std::index_sequence<Is...> ) {
return std::integer_sequence<E, static_cast<E>(Is)... >{};
}
template<class E>
constexpr auto enum_list() {
return enum_list<E>( enum_indexes_v<E> );
}

template<class Es>
struct to_initializer_list;
template<class E, E... es>
struct to_initializer_list< std::integer_sequence<E,es...> > {
static inline constexpr std::initializer_list<E> list = {es...};
};
template<class E>
constexpr auto enum_il_v = to_initializer_list< decltype( enum_list<E>() ) >::list;

则CCD_ 4是引用包含a到D的全局范围数组的初始化器列表。

这里的密钥是(a(CCD_;著名的";我们将枚举的末尾添加到枚举中,并且(b(枚举的元素从0到ENUM_COUNT是连续的,但不包括。

您可以通过添加不同的方法来获得计数,从而绕过ENUM_COUNT。使用这种技术,除非元素与其他简单的已知模式相匹配,否则无法解决元素连续的需求。

其他替代方案包括等待反射到达C++,或者使用宏或其他预处理技术(如代码生成(。

相关内容

最新更新