n维数组构造函数的模板规范

Deu*_*uro 3 c++

我正在实现一个n维数组类,它是一个模板如下(请注意,数据存储在一个线性数组中,其长度是所有维度的乘积):

template< class valType, int rank >
class NDimensionalArray
{
public:

private:
    valType* m_data;
    int* m_dimensions;
    int m_rank;
};
Run Code Online (Sandbox Code Playgroud)

所以我的想法是用户(我)可以指定排名2和某个维度的数组,即:

NDimensionalArray<double,2> matrix(10,10);
Run Code Online (Sandbox Code Playgroud)

现在困难在于专门构造1-> n维的构造函数,每个构造函数需要n个参数,其中n是数组的等级.现在我想到使用像printf()中使用的valarray,但是这个定义了一个具有2维的1维数组,即:

NDimensionalArray<double,1> matrix(10,10);
Run Code Online (Sandbox Code Playgroud)

是完全可以接受的行为.我可以使用一些巧妙的技巧让编译器重复吗?实际上只要我知道排名,并且具有每个维度的长度,构造函数就可以是通用的:

{
    int nElements = m_dimensions[0];
    for ( int i=1 ; i<m_rank ; ++i )
        nElements *= m_dimensions[i];
    m_data = new valType[nElements];
}
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,访问者将需要类似的操作.

此外,我已经考虑了一个构造函数的选项,看起来像:

NDimensionalArray( const NDimensionalArray<int,1>& dimensions );
Run Code Online (Sandbox Code Playgroud)

可以使用如下:

NDimensionalArray<int,1> dimVec(2); // Need a specification for 1-dimensional arrays.
dimVec(0) = 10;
dimVec(1) = 10;
NDimensionalArray<double,2> matrix(dimVec);
Run Code Online (Sandbox Code Playgroud)

这将是一个可行的解决方案,但与我想要的用途相比它很难看.访问多维数组也会变得非常痛苦,并且必须为每次访问构建维度向量非常慢.

Pav*_*aev 7

好的,我已经玩了一段时间了.这是一些模板元编程hackery,它可以完成你想要的东西.它允许您指定内联的所有维度,它不执行任何动态内存分配或其他此类事情.此外,使用一个好的C++编译器(我用VC++ /O2选项测试),代码将完全内联,没有完成复制(事实上,对我来说,它在调用点内联整个NDimensionalArray构造函数).它会在编译时完全进行类型检查,并且不会让你传递太少或太多的维度.它可以重复用于索引器.开始:

template<class T, int N>
class value_pack : private value_pack<T, N-1>
{
public:

    enum { size = N };

    value_pack(value_pack<T, N-1> head, const T& tail)
        : value_pack<T, N-1>(head)
        , value(tail)
    {
    }

    value_pack<T, N+1> operator() (const T& tail) const
    {
        return value_pack<T, N+1>(*this, tail);
    }

    template<int I>
    const T& get() const
    {
        return this->value_pack<T, I+1>::value;
    }

protected:

    const T value;
};

template<class T>
struct value_pack<T, 0>
{
};

struct
{
    template <class T>
    value_pack<T, 1> operator() (const T& tail) const
    {
        return value_pack<T, 1>(value_pack<T, 0>(), tail);
    }
} const values;


template <class ValType, int Rank>
struct NDimensionalArray
{
    NDimensionalArray(value_pack<ValType, Rank> values)
    {
        // ...
    }
};


int main()
{
    NDimensionalArray<int, 3> a(values(1)(2)(3));
}
Run Code Online (Sandbox Code Playgroud)