【发布时间】:2014-06-21 02:45:06
【问题描述】:
如果我想设置一个指向多维 C++ 数组的第一个元素的指针,我可以轻松做到:
double arr[2][3][4];
double *p;
p = &arr[0][0][0];
如何对任意等级的数组执行此操作?接收对多维数组的引用的函数可以写成如下:
template <typename T, unsigned N>
void receive(T (&a)[N]) {}
C++11 std::remove_all_extents 类模板可用于获取数组的(最深的)元素类型。这可以帮助使用typename std::remove_all_extents<T>::type * 构造receive 的修改版本的返回类型。但是返回的value应该如何创建呢?
以下解决方案使用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); }
或者,以下解决方案使用递归,虽然类型系统仍然强大,但递归可能会引入额外的指令。
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])); }
一般如何获取多维数组的第一个元素的地址?有零开销的强类型解决方案吗?
【问题讨论】:
-
reinterpret_cast解决方案中没有强类型化的内容是什么? IMO 很好,我认为没有比这更好的了。 -
我没有练习元编程魔法,但我很确定解决方案将涉及
std::rank。 -
reinterpret_cast版本没有问题 - 数组保证没有初始填充。我想知道remove_all_extents是否无论如何都不是通过递归模板实现的。 -
remove_all_extents将使用递归实现。这里计算的结果是一个类型 - 这必须在编译时完成。
标签: c++ arrays templates types multidimensional-array