声明多维std :: array的冗长方式

NoS*_*tAl 17 c++ multidimensional-array c++11

简短的问题:有没有更短的方法来做到这一点

array<array<atomic<int>,n>,m> matrix;
Run Code Online (Sandbox Code Playgroud)

我希望有类似的东西

array< atomic< int>,n,m> matrix;    
Run Code Online (Sandbox Code Playgroud)

但它不起作用......

How*_*ant 32

模板别名可能会有所帮助:

#include <array>

template <class T, unsigned I, unsigned J>
using Matrix = std::array<std::array<T, J>, I>;

int main()
{
    Matrix<int, 3, 4> matrix;
}
Run Code Online (Sandbox Code Playgroud)

  • 霍华德的例子对我来说有点混乱,因为矩阵*不*映射到int [3] [4].相反,它就像int [4] [3].定义int [4] [3]是一个包含4个元素的数组,其中每个元素是3个整数的数组.这就是上面使用std :: array定义的内容.一致认为I和J应该在Matrix的模板别名中交换.更好的是,他们应该重命名行和列. (7认同)
  • 我在发布之前在clang/OS X上测试过它. (3认同)

ild*_*arn 31

对于不支持模板别名的编译器来说,一个可口的解决方法是使用一个简单的元函数来生成类型:

#include <cstddef>
#include <array>

template<class T, std::size_t RowsN, std::size_t ColumnsN>
struct Matrix
{
    typedef std::array<std::array<T, ColumnsN>, RowsN> type; // row major

private:
    Matrix(); // prevent accidental construction of the metafunction itself
};

int main()
{
    Matrix<int, 3, 4>::type matrix;
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*ice 12

使用可变参数模板的解决方案(稍微比模板别名复杂,但更通用)

template <typename T, std::size_t thisSize, std::size_t ... otherSizes>
class multi_array : private std::array<multi_array<T, otherSizes...>, thisSize>
{
 using base_array = std::array<multi_array<T, otherSizes...>, thisSize>;

 public:
    using base_array::operator[];
    // TODO: add more using statements to make methods
    // visible.  This is less typing (and less error-prone)
    // than forwarding to the base_array type.
};

template <typename T, std::size_t thisSize>
class multi_array<T, thisSize> : private std::array<T, thisSize>
{
 using base_array = std::array<T, thisSize>;

 public:
    using base_array::operator[];
    // TODO: add more using statements to make methods
    // visible.  This is less typing (and less error-prone)
    // than forwarding to the base_array type.
};
Run Code Online (Sandbox Code Playgroud)

分配给可以制作的数组的非叶子可能会有一些改进.

我测试了一个相对较新的clang/LLVM构建.

请享用!


Ric*_*y65 11

嵌套时,std :: array可能变得非常难以阅读并且不必要地冗长.尺寸的相反排序可能特别令人困惑.

例如:

std::array < std::array <int, 3 > , 5 > arr1; 
Run Code Online (Sandbox Code Playgroud)

相比

char c_arr [5][3]; 
Run Code Online (Sandbox Code Playgroud)

另外,请注意,当嵌套std :: array时,begin(),end()和size()都返回无意义的值.

由于这些原因,我创建了自己的固定大小的多维数组容器,array_2d和array_3d.它们的优点是它们可以与C++ 98一起使用.

它们类似于std :: array,但适用于2维和3维的多维数组.它们比内置的多维数组更安全,性能更差.我没有包含尺寸大于3的多维数组的容器,因为它们并不常见.在C++ 11中,可以制作一个支持任意数量维度的可变参数模板版本(像Michael Price的例子).

二维变体的一个例子:

//Create an array 3 x 5 (Notice the extra pair of braces) 
fsma::array_2d <double, 3, 5> my2darr = {{ 
{ 32.19, 47.29, 31.99, 19.11, 11.19}, 
{ 11.29, 22.49, 33.47, 17.29, 5.01 }, 
{ 41.97, 22.09, 9.76, 22.55, 6.22 } 
}};  
Run Code Online (Sandbox Code Playgroud)

完整文档可在此处获得:http: //fsma.googlecode.com/files/fsma.html

您可以在此处下载该库:http: //fsma.googlecode.com/files/fsma.zip

  • 也许毫无意义的话太强烈了.我的意思是它不返回多维数组中的元素总数.顺便说一下,我同意它应该符合标准.可以替代不安全的内置多维数组:) (4认同)
  • 顺便说一句,为什么 .size() 毫无意义?它的行为不符合预期吗?arr.size()==dim1, arr[0].size()=dim2 (2认同)