如何在 C++ 中定义数组数组

how to define an array of array in c++

本文关键字:数组 定义 C++      更新时间:2023-10-16

>我有这个定义:

typedef uint8_t myType[16];
constexpr myType x0 = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
constexpr myType x1 = {11,12,13,14,15,16,17,18,19,10,11,12,13,14,15,16};
constexpr myType x2 = {21,22,23,24,25,26,27,28,29,20,21,22,23,24,25,26};
constexpr myType AllX[] = {x0,x1,x2};

在VS 2015中编译它,给我这个错误:

An internal error has occurred in the compiler. 

智能感知报告此错误:

类型为"const uint8_t *"的值不能用于初始化类型为"const uint8_t"的实体

如何解决此问题?

您可以使用std::array来解决问题。

#include <array>
using myType = std::array<uint8_t, 16>;
int main()
{
constexpr myType x0={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
constexpr myType x1={11,12,13,14,15,16,17,18,19,10,11,12,13,14,15,16};
constexpr myType x2={21,22,23,24,25,26,27,28,29,20,21,22,23,24,25,26};
constexpr std::array<myType, 3> AllX = {x0,x1,x2};
}

在评论中,你说,

但是我不能使用这种方法,因为x0x1x2和..已经在代码中以这种方式定义,我无法更改它。

在这种情况下,您唯一的选择是将这些对象的元素复制到AllX.您可以使用std::copy来简化它。唯一的问题是你不能使用constexpr AllX.

std::array<myType, 3> AllX = {};
std::copy(begin(x0), end(x0), AllX[0].data());
std::copy(begin(x1), end(x1), AllX[1].data());
std::copy(begin(x2), end(x2), AllX[2].data());

一个数组只能用大括号括起来的初始值设定项初始化,不能用另一个数组初始化。有关更多详细信息,请参阅聚合初始化。

修复:

constexpr myType AllX[] = {
{1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6},
{11,12,13,14,15,16,17,18,19,10,11,12,13,14,15,16},
{21,22,23,24,25,26,27,28,29,20,21,22,23,24,25,26}
};
constexpr auto& x0=AllX[0];
constexpr auto& x1=AllX[1];
constexpr auto& x2=AllX[2];

在 C 中,可以将 AllX[] 声明为指向基础成员的指针数组。 这将失去编译器知道它们的大小为 16,但我不知道这对您有多重要。当然,你/可以/在 c++ 中做到这一点:

constexpr uint8_t *AllX[]={x0,x1,x2};

为了证明损失,您可以将其写为:

constexpr uint8_t *AllX[]={&x0[0],&x1[0],&x2[0]};

您可以使用 2 组 [] 对此进行索引,例如 AllX[1][5]

或者,您可以声明一个轻量级对象,该对象在其构造函数中引用固定数量的 myType 对象,并提供运算符重载来执行外部索引。在内部,该对象也可以有一个 C 数组或指向 mytype 的指针的 std::数组,并逐步执行该指针。您可以将其扩展到生成模板类的模板函数,以允许两个数组具有编译时确定的大小。

此对象还可以获得子数组的所有权,从其自身的销毁中调用成员上的某种销毁方法。

当你谈论单个平面数组时,你是说你想让 AllX[25 找到 X1[9]?如果是这样,您可以使用轻量级包装器对象运算符执行此操作。它可以对索引执行必要的简单数学运算以获取外部和内部索引,并返回对相关成员的 (const( 引用。