2013-05-21 47 views
2

我可以打一个多维数组一样可变参数多维数组

func(0,0,0); //=> if I know it's dimension on the run time. 
func(0,0,0,0,0,0,0,0,0,0,0); //=> if I know it's dimension on the run time. 

通过的可变参数模板

,而不是帮助:

data[0][0][0]; 
data[0][0][0][0][0][0][0][0][0][0][0]; 
+2

你想创建一个数组,或从中获取一个元素? – soon

+0

更多细节或用例会有所帮助。不知道你为什么/你想做什么。 – ChrisCM

回答

4

这应该工作,但不是做data[1][2][3],你将不得不使用indexed(data,1,2,3)

它为plain arrays以及std::arrays。您只需复制专业化即可扩展它std::vector。 (我觉得应该为重载的operator [],但不能确定任何事情的工作。


#include <iostream> 
#include <array> 

template<typename T, size_t dim> 
struct getTypeAtDim { typedef T type; }; 

template<typename T, size_t N> 
struct getTypeAtDim<T[N],1> { typedef T type; }; 

template<typename T, size_t dim, size_t N> 
struct getTypeAtDim<T[N],dim> : getTypeAtDim< T, dim-1> {}; 

template<typename T, size_t N> 
struct getTypeAtDim<std::array<T,N>,1> { typedef T type; }; 

template<typename T, size_t dim, size_t N> 
struct getTypeAtDim<std::array<T,N>,dim> : getTypeAtDim< T, dim-1> {}; 

template<typename T, size_t dim> 
using typeAtDim = typename getTypeAtDim<T, dim>::type; 

template<typename T> 
typeAtDim<T,1>& 
indexed(T& arr, const int& first) { 
    return arr[first]; 
} 

template<typename T, typename... Args> 
typeAtDim<T,sizeof...(Args) + 1>& 
indexed(T& arr, const int& first, const Args& ...rest) { 
    return indexed(arr[first],rest...); 
} 

int main() { 
    std::array<int,2> a1 = {1,2}; 
    std::array<int,2> a2 = {3,4}; 
    std::array<std::array<int,2>,2> a = {a1,a2}; 
    std::array<std::array<std::array<int,2>,2>,2> c = {a,a}; 
    int b[2][2] = {{5,6},{7,8}}; 


    std::cout << indexed(a,1,1) << std::endl; 
    indexed(a,1,1) = 5; 
    std::cout << indexed(a,1,1) << std::endl; 
    std::cout << indexed(b,1,1) << std::endl; 
    std::cout << indexed(c,1,1,1) << std::endl; 
    indexed(c,1,1) = a1; 
    std::cout << indexed(c,1,1,1) << std::endl; 
} 

4 5 8 4 2 

Here is a test run。推断返回的类型时


我不使用 autotrailing return types因为 indexed一个可变版本

将不匹配自身。因此,直到gcc得到解决,你将不得不使用这样的东西。

+0

非常感谢你,很棒的解决方案。 – Alper

+0

@Avatar很高兴帮助。其实我可能会自己使用它。比在生成的代码中始终执行[] []更容易。所以感谢你提出这个想法:) – stardust

0

可以重载运算符()。我不确定它是否会帮助你很多。

如果您正在使用C++ 11,您可以创造性地思考如何使用initializer_list。