我有大枚举例如:
enum { elem0, elem1, elem2, elem3 ...... elem1000 }
我想使用一些枚举元素创建一个float
数字数组。
例如,我想在数组中只有三个元素:elem0
,elem7
,elem999
,我想以类似的方式对它们进行处理:
array[elem0]=123
array[elem7]=12.5
array[elem999]=15.6
实现这样一个数组的最优雅的方法是什么,以便数组只有三个元素?
答案 0 :(得分:2)
只需编写从枚举到数组索引的转换:
int EnumToIdx(Elem elem)
{
switch (elem)
{
case elem0: return 0;
case elem7: return 1;
case elem999: return 2;
}
throw std::invalid_argument("EnumToIdx: no conversion"); // or whatever
}
用法
array[EnumToIdx(elem0)] = 123;
array[EnumToIdx(elem7)] = 12.5;
array[EnumToIdx(elem999)] = 15.6;
答案 1 :(得分:0)
也许是矫枉过正,但也许不是 - 模板扩展可以为你编写转换函数。
此模板类允许您指定哪些元素应对矢量有效,以及按顺序排列。
它还提供了通过elem索引向量的能力,动态(如果不存在则抛出异常)或静态(如果超出界限则无法编译)。
#include <array>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <stdexcept>
//
// boilerplate
//
namespace notstd {
template<class T, class Tuple>
struct tuple_index;
template<class T, class... Types>
struct tuple_index<T, std::tuple<T, Types...>> {
using type = std::size_t;
static const type value = 0;
};
template<class T, class U, class... Types>
struct tuple_index<T, std::tuple<U, Types...>> {
using type = std::size_t;
static const type value = 1 + tuple_index<T, std::tuple<Types...>>::value;
};
}
enum element_type {
elem0, elem1, elem2, elem3, elem4, elem5, elem1000
};
template<element_type Value>
struct where_type
{
static const element_type value = Value;
};
template<element_type Value>
static constexpr auto where = where_type<Value> {};
template<element_type...Permitted>
struct restricted_vector : private std::array<double, sizeof...(Permitted)> {
using corresponding_tuple = std::tuple<where_type<Permitted>...>;
using inherited = std::array<double, sizeof...(Permitted)>;
using inherited::inherited;
static auto conversion(element_type e) -> std::size_t
{
static const std::array<std::pair<element_type, std::size_t>, sizeof...(Permitted)> a = {
std::make_pair(Permitted, notstd::tuple_index<where_type<Permitted>, corresponding_tuple>::value)...
};
auto ifind = std::find_if(a.begin(), a.end(), [e](auto&& elem) { return elem.first == e; });
if (ifind == a.end()) {
throw std::out_of_range("invalid element");
}
return ifind->second;
}
template<element_type Elem>
auto& operator[](where_type<Elem>) {
auto pos = notstd::tuple_index<where_type<Elem>, corresponding_tuple >::value;
return inherited::operator[](pos);
}
template<element_type Elem>
auto const& operator[](where_type<Elem>) const {
auto pos = notstd::tuple_index<where_type<Elem>, corresponding_tuple >::value;
return inherited::operator[](pos);
}
// dynamic access
auto& at(element_type e) {
return inherited::operator[](conversion(e));
}
auto const& at(element_type e) const {
return inherited::operator[](conversion(e));
}
using inherited::begin;
using inherited::end;
using inherited::size; // etc
};
int main() {
auto v1 = restricted_vector<elem3, elem4, elem5> {};
v1[where<elem4>] = 0.4;
v1[where<elem5>] = 0.5;
v1[where<elem3>] = 0.3;
std::copy(v1.begin(), v1.end(), std::ostream_iterator<double>(std::cout, ", "));
std::cout << "\n";
std::cout << "at elem4: " << v1.at(elem4) << std::endl;
}
预期产出:
0.3, 0.4, 0.5,
at elem4: 0.4