這裏是彼得的解決辦法收拾了一下,除去他的enable_if專業化,並再次使用索引招吧。另外,我概括爲下面的例子中的語法用於任何數目的一組值:
makeNDimensionalArray<char, I<3,6,5,4>, I<2,4,3,2, 0,1,2,3, 1,2,4,3>, I<0,0,0,0, 2,3,1,2>, I<1,1,2,1>>('a','b','c')
其中I<3,6,5,4>
設置多陣列的尺寸。然後I<2,4,3,2, 0,1,2,3, 1,2,4,3>
將數組的這三個索引位置設置爲'a',I<0,0,0,0, 2,3,1,2>
將數組的這兩個索引位置設置爲'b',等等。
#include <iostream>
#include <array>
#include <tuple>
#include <utility>
template <typename, std::size_t, std::size_t...> struct NArray;
template <typename T, std::size_t NumDimensions, std::size_t N>
struct NArray<T, NumDimensions, N> {
using type = std::array<T, N>;
};
template <typename T, std::size_t NumDimensions, std::size_t First, std::size_t... Rest>
struct NArray<T, NumDimensions, First, Rest...> {
using type = std::array<typename NArray<T, NumDimensions, Rest...>::type, First>;
};
template <typename T, std::size_t... Dimensions>
using NDimensionalArray = typename NArray<T, sizeof...(Dimensions), Dimensions...>::type;
template <typename T, typename Dimensions> struct NArrayFromPack;
template <typename T, template <std::size_t...> class P, std::size_t... Dimensions>
struct NArrayFromPack<T, P<Dimensions...>> : NArray<T, sizeof...(Dimensions), Dimensions...> {
static constexpr std::size_t num_dimensions = sizeof...(Dimensions);
};
template <typename A, typename T>
void setArrayValue (A& a, const T& t) { a = t; }
template <std::size_t First, std::size_t... Rest, typename Array, typename T>
void setArrayValue (Array& array, const T& t) {
setArrayValue<Rest...>(array[First], t);
}
template <typename Indices, typename Sequence> struct InitializeArray;
template <template <std::size_t...> class P, std::size_t... Is, std::size_t... Js>
struct InitializeArray<P<Is...>, std::index_sequence<Js...>> {
template <typename Array, typename T>
static void execute (Array& array, const T& t) {
constexpr std::size_t GroupSize = sizeof...(Js), NumGroups = sizeof...(Is)/GroupSize;
set<GroupSize>(array, t, std::make_index_sequence<NumGroups>{});
}
private:
template <std::size_t GroupSize, typename Array, typename T, std::size_t... Ks>
static void set (Array& array, const T& t, std::index_sequence<Ks...>) {
const int dummy[] = {(do_set<Ks, GroupSize>(array, t), 0)...};
static_cast<void>(dummy);
}
template <std::size_t N, std::size_t GroupSize, typename Array, typename T>
static void do_set (Array& array, const T& t) {
constexpr std::size_t a[] = {Is...};
setArrayValue<a[N*GroupSize + Js]...>(array, t);
}
};
template <typename T, typename Dimensions, typename... Indices, typename... Args>
auto makeNDimensionalArray (const Args&... args) {
using A = NArrayFromPack<T, Dimensions>;
typename A::type array;
const int a[] = {(InitializeArray<Indices, std::make_index_sequence<A::num_dimensions>>::execute(array, args), 0)...};
static_cast<void>(a);
return array;
}
template <std::size_t...> struct I;
int main() {
const NDimensionalArray<char, 3,6,5,4> a = makeNDimensionalArray<char, I<3,6,5,4>, I<2,4,3,2, 0,1,2,3, 1,2,4,3>, I<0,0,0,0, 2,3,1,2>, I<1,1,2,1>>('a','b','c');
std::cout << a[2][4][3][2] << std::endl; // a
std::cout << a[0][1][2][3] << std::endl; // a
std::cout << a[1][2][4][3] << std::endl; // a
std::cout << a[0][0][0][0] << std::endl; // b
std::cout << a[2][3][1][2] << std::endl; // b
std::cout << a[1][1][2][1] << std::endl; // c
}
我認爲我有怎樣的一個的[相關問題一次(http://stackoverflow.com/questions/18251815/creating-an-array-initializer-from-a-tuple-or-variadic-template α參數)。請不要在意問題太多,請檢查有用的答案。 – 2014-10-31 20:51:10
什麼是你的算法是什麼意思?你怎麼知道它是一個有2個元素的4維陣列與5個元素的2維陣列? – Barry 2014-10-31 20:52:38
你不能有這樣的多個非推導參數包,編譯器無法知道哪裏結束,另一個開始 – Brian 2014-10-31 20:53:13