首先,您违反了DRY。喜欢的东西
std::vector<std::array<byte_t, 1>> arr_1;
std::vector<std::array<byte_t, 2>> arr_2;
... up to ....
std::vector<std::array<byte_t, 50>> arr_50;
:
替换此
template<typename Pack, unsigned X> struct append;
template<template<unsigned...>class Pack, unsigned... Xs, unsigned X>
struct append<Pack<Xs...>, X> {
typedef Pack<Xs..., X> type;
};
template<typename Pack, unsigned X> using Append=typename append<Pack,X>::type;
template<unsigned N, template<unsigned>class Contents>
struct auto_tuple {
typedef Append< typename auto_tuple<N-1, Contents>::type, Contents<N-1> > type;
};
template<template<unsigned>class Contents>
struct auto_tuple<0, Contents> {
typedef std::tuple<> type;
};
template<unsigned N, template<unsigned>class Contents>
using AutoTuple = typename auto_tuple<N,Contents>::type;
其中AutoTuple<N, Contents>
通过N-1
适用0
到Contents
并产生std::tuple
出来。写:
template<typename T, unsigned N>
using vec_of_array = std::vector<std::array<T, N>>;
template<unsigned N>
using vec_of_byte_array = vec_of_array<byte_t, N>;
template<unsigned N>
using get_nth_byte_array = vec_of_byte_array<N+1>;
您可以使用它填充您tuple
,如:
typedef AutoTuple<50, get_nth_byte_array> my_tuple;
这是50
的std::tuple
不同std::vector
S,其中每个存储1
一个std::array
通过50
byte
秒。
这花费的时间远远少于50
行,虽然这很难让它工作并理解它,但这意味着代码是一致的并且只生成一次:一条特定行的机会要少得多错误的,以及一次性错误的可能性要高得多。您可以使用编译时间值通过std::get<7>(my_tuple)
提取第n个元素。哦,如果你想要100
或10
而不是50
?改变一个常量。
接着,contiguous_range
结构,基本上是一打扮对指针给你一个类型擦除的方式来看待N
元件的阵列(或其它缓冲剂),像Passing a std::array of unknown size to a function
现在,则可以手动编写你的大开关语句,或者你可以建立一个函数指针表,提取contiguous_range
并自动构建它。
// DataStorage is the tuple of std::vector of std::array
template<unsigned...> struct seq{};
template<unsigned max, unsigned... s> struct make_seq:make_seq<max-1, max-1, s...> {};
template<unsigned... s> struct make_seq<0,s...>:seq<s...> {};
template<unsigned N>
struct get_array {
static contig_range<byte> get(DataStorage& data, unsinged idx) {
return (std::get<N>(std::forward<Data>(data))[idx];
}
};
存储在阵列
和建立的它们中的50(每个具有不同的N
)的阵列:
typedef contig_range<byte> (*array_getter)(DataStorage&, unsigned idx);
template<unsigned N, unsigned... S>
std::array< array_getter, N > populate_array_helper(seq<S...>) {
return { get_array<S>::get... };
}
template<unsigned N>
std::array< array_getter, N > populate_array() {
return populate_array_helper(make_seq<N>());
}
,然后可以使用运行时间参数来查找,调用它,并且您得到一个类型为byte
的连续数组的实例。
非代码开销是50个指针(查找表),3个指针(包含向量)。
你永远不会做50次相同代码的cpoy /粘贴,每次更改一个单一的数字,其中一个有一个轻微的错字,会产生一个微妙的fenceposting错误,只发生在一个晦涩难懂仅在发布模式下重现测试用例。
erm,返回一个'std :: vector <>'? – Nim
我忘了&。我必须有能力修改这个数组。 – Dejwi
您可以返回对矢量的引用,并将其修改为您的心灵内容... – Nim