Я хотел бы держать массив целых чисел в моей структуре
struct HPDF_TableAttributes
{
HPDF_REAL rows;
HPDF_REAL cols;
HPDF_REAL rowH;
HPDF_REAL colW;
HPDF_REAL tabX;
HPDF_REAL tabY;
HPDF_REAL tabH;
HPDF_REAL tabW;
HPDF_Font font;
HPDF_REAL fontSize;
int colRatios[]; /// HERE
};
Кажется, неважно, как я это делаю, компилятор хочет, чтобы я инициализировал это здесь? Должен ли я сделать это? Я пытаюсь сделать что-то вроде следующего для использования.
HPDFTableAttributes oTACent;
oTACent.rows = 3; oTACent.cols = 3;
oTACent.rowH = 20; oTACent.colW = pageWidth-70/oTACent.cols;
oTACent.tabH = oTACent.rows * oTACent.rowH;
oTACent.tabW = oTACent.cols * oTACent.colW;
oTACent.tabX = 35; oTACent.tabY = pageHeight - oTACent.tabH - 45;
oTACent.font = fontTimesBold; oTACent.fontSize = 20;
oTACent.colRatios = [1, 1, 2]; /// HERE
Затем я отправляю эти атрибуты в свою функцию, которая превращает меня в таблицу и использует отношение значений в этом целочисленном массиве к пробелам столбцов в тех же строках.
void CReport::putTableOnPdf(HPDF_Page page, HPDFTableAttributes tabAtt, array_2d<CString> tabDat)
{
// Table Outline
HPDF_Page_SetLineWidth (page, 1);
HPDF_Page_Rectangle (page, tabAtt.tabX, tabAtt.tabY, tabAtt.tabW, tabAtt.tabH);
// Table row lines
HPDF_REAL rowsPut = 0;
while(rowsPut < tabAtt.rows)
{
rowsPut++;
HPDF_Page_MoveTo (page, tabAtt.tabX, tabAtt.tabY + rowsPut*tabAtt.rowH);
HPDF_Page_LineTo (page, tabAtt.tabX + tabAtt.tabW, tabAtt.tabY + rowsPut*tabAtt.rowH);
}
// Table col lines
/*int colRatioSum = 0;
for(int i = 0; i < tabAtt.colRatios.length; i++)
colRatioSum += tabAtt.colRatios[i];
tabAtt.colW = tabAtt.colW / colRatioSum;*/ /// HERE
HPDF_REAL colsPut = 0;
while(colsPut < tabAtt.cols)
{
colsPut++;
HPDF_Page_MoveTo (page, tabAtt.tabX + colsPut*tabAtt.colW, tabAtt.tabY);
HPDF_Page_LineTo (page, tabAtt.tabX + colsPut*tabAtt.colW, tabAtt.tabY + tabAtt.tabH);
}
HPDF_Page_Stroke (page);
}
В C ++ размер массива является частью его типа. * Существует специальное правило, которое позволяет объявлению массива определять его размер из инициализатора, поэтому вам не всегда нужно явно писать тип.
Вы также можете написать и использовать неполный вводит в определенных обстоятельствах, но вы не можете делать с ними ничего, что требует полного типа.
Итак, проблема здесь в том, что вы пишете неполный тип и делаете с ним что-то, что требует полного типа (а именно, объявление объекта этого типа). Добавление инициализатора является одним из способов объявить размер массива и, таким образом, завершить тип, что позволяет избежать ошибки.
Если вы действительно хотите сказать «а последнее поле представляет собой набор целых чисел», то вам нужно использовать тип, который может это представить (опять же, массивы имеют фиксированное количество элементов). В C ++ наиболее очевидное решение std::vector<int>
, С помощью std::vector
Вы можете написать свой псевдокод почти точно:
oTACent.colRatios = {1, 1, 2};
Другой вариант, который вы можете увидеть, но не стоит писать, это использовать указатель. C ++ определяется так, что вы можете использовать указатель на элемент массива аналогично массиву. Поскольку тип указателя не включает размер массива, тот же тип указателя может использоваться с массивом любого размера.
* некоторые компиляторы поддерживают элементы массива переменной длины в качестве расширения, где размер массива определяется при инициализации структуры, но это не стандартный C ++, и он все же требует, чтобы размер был известен при инициализации (а не из более поздней версии). присваивание, как в вашем псевдокоде, где вы присваиваете массиву). Есть еще одно расширение, называемое «гибкие массивы», в котором последний член может быть объявлен без размера, а затем вы вручную выделяете достаточно памяти для всей структуры плюс размер, который вам нужен для массива.
Размер массива должен быть известен во время объявления, так как он является частью его типа. Поэтому вы должны изменить это на что-то вроде:
int colRatios[3];
Кроме того, присвоение массива не работает так, как вы пытаетесь:
oTACent.colRatios = [1, 1, 2];
Там нет такого синтаксиса в C ++. Если вы хотите легко присваивать такие значения, вы можете использовать C ++ 11 и std :: vector:
std::vector<int> colRatios;
// ...
oTACent.colRatios = {1, 1, 2};