Как определить массив массива в C ++ - PullRequest
0 голосов
/ 22 мая 2018

У меня есть следующие определения:

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. 

Intel сообщает об этой ошибке:

значение типа "const uint8_t *" нельзя использовать для инициализации объекта типа "const uint8_t"

Как я могу решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Вы можете использовать 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};
}

В комментарии вы сказали:

Но я не могу использовать этот методтак как x0 и x1 и x2 и .. уже определены таким образом в коде, и я не могу изменить его.

В этом случае единственный вариант - скопировать элементы этих объектов в 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());
0 голосов
/ 22 мая 2018

В 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-массив или std :: массив указателей на mytype и проходить через этот указатель.Возможно, вы могли бы расширить это до функции-шаблона, которая генерирует класс-шаблон, чтобы позволить двум массивам иметь размеры, определенные во время компиляции.

Этот объект может также стать владельцем дочерних массивов, вызывая некоторый метод уничтожения вчлены от его собственного уничтожения.

Когда вы говорите об одном плоском массиве, вы говорите, что хотите, чтобы AllX [25 нашел X1 [9]?Если это так, вы можете сделать это с помощью облегченного оператора объекта-оболочки.Он может выполнить необходимую тривиальную математику для индекса, чтобы получить внешние и внутренние индексы, и вернуть (const) ссылку на соответствующий элемент.

0 голосов
/ 22 мая 2018

Массив можно инициализировать только с помощью заключенного в скобки инициализатора , но не с другим массивом.См. агрегатная инициализация для получения более подробной информации.

Исправление:

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];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...