通常获得指向多维C ++数组的第一个元素的指针

时间:2014-05-04 21:12:42

标签: c++ arrays templates types multidimensional-array

如果我想设置一个指向多维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类模板可用于获取数组(最深)元素类型。这可以帮助使用receivetypename 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); }

或者,以下解决方案使用递归,虽然类型系统仍然很强,但递归可能会引入其他指令。

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])); }

如何获得多维数组的第一个元素的地址?是否存在零开销的强类型解决方案?

1 个答案:

答案 0 :(得分:0)

#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';
}