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];
4

2 回答 2

4

这应该可以工作,但data[1][2][3]你必须使用而不是这样做indexed(data,1,2,3)

它适用plain arraysstd::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.


我没有使用autowith ,trailing return types因为在推断 return 的类型时,可变参数版本indexed不会匹配自身。因此,在您解决此问题之前,gcc您将不得不使用这样的东西。

于 2013-05-21T19:37:05.330 回答
0

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

如果您使用的是 C++11,您可能会创造性地考虑使用 initializer_list。

于 2013-05-21T17:23:24.277 回答