我可以把多维数组命名为
吗?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];
这应该可以工作,但不是使用data[1][2][3]
,而是使用indexed(data,1,2,3)
适用于plain arrays
和std::arrays
。您可以通过复制专门化来扩展std::vector
。(我认为它应该适用于任何重载操作符[]的东西,但不确定。)
#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
.
我没有使用auto
和trailing return types
,因为 indexed
的可变版本在推断返回的类型时将不匹配自身。所以在gcc
解决这个问题之前,你必须使用这样的东西
可以重载操作符()。我不确定它是否会对你有很大帮助。
如果你正在使用c++ 11,你可以创造性地考虑使用initializer_list