use*_*370 5 c++ arrays templates types multidimensional-array
如果我想设置一个指向多维 C++ 数组的第一个元素的指针,我可以轻松做到:
double arr[2][3][4];
double *p;
p = &arr[0][0][0];
Run Code Online (Sandbox Code Playgroud)
如何对任意等级的数组执行此操作?接收多维数组引用的函数可以写成如下:
template <typename T, unsigned N>
void receive(T (&a)[N]) {}
Run Code Online (Sandbox Code Playgroud)
C++11std::remove_all_extents类模板可用于获取数组的(最深的)元素类型。receive这可以帮助构建using的修改版本的返回类型typename std::remove_all_extents<T>::type *。但是返回值应该如何创建呢?
以下解决方案使用reinterpret_cast. 这大概会被有效地执行,但我不喜欢reinterpret_cast对类型系统的规避。
template <typename T, unsigned N>
typename std::remove_all_extents<T>::type *
to_ptr1(T (&a)[N]) { return reinterpret_cast<
typename std::remove_all_extents<T>::type *
>(&a); }
Run Code Online (Sandbox Code Playgroud)
或者,以下解决方案使用递归,并且虽然类型系统仍然强大,但递归可能会引入额外的指令。
template <typename T> T *to_ptr2(T &a) { return &a; }
template <typename T, unsigned N>
typename std::remove_all_extents<T[N]>::type *
to_ptr2(T(&a)[N]) { return to_ptr2(*(&a[0])); }
Run Code Online (Sandbox Code Playgroud)
一般如何获取多维数组第一个元素的地址?是否有零开销的强类型解决方案?
#include <iostream>
#include <type_traits>
template<size_t Rank>
struct deref_n
{
template<typename T>
auto operator()(T& ptr) -> decltype(deref_n<Rank-1>()(*ptr))
{
return deref_n<Rank-1>()(*ptr);
}
};
template<>
struct deref_n<0>
{
template<typename T>
T& operator()(T& val)
{
return val;
}
};
template<typename T>
auto first_element(T& val) -> decltype(deref_n<std::rank<T>::value>()(val))
{
return deref_n<std::rank<T>::value>()(val);
}
int main()
{
int x[10][20][30] = {};
first_element(x) = 777; // this gives me a reference to x[0][0][0]
std::cout << x[0][0][0] << '\n';
}
Run Code Online (Sandbox Code Playgroud)