我可以调用一个多维数组吗
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];
我可以调用一个多维数组吗
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
您可以通过复制专业化来扩展它。(我认为它应该适用于任何重载 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
我没有使用auto
with ,trailing return types
因为在推断 return 的类型时,可变参数版本indexed
不会匹配自身。因此,在您解决此问题之前,gcc
您将不得不使用这样的东西。
您可以重载运算符()。我不确定它是否会对你有很大帮助。
如果您使用的是 C++11,您可能会创造性地考虑使用 initializer_list。