Question

I would like to hold an array of integers in my struct

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
};

It seems not matter how I do it, the compiler wishes me to to initialize it here? Must I do that? I am trying to do something along the lines of the following for usage.

    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

Then I send these attributes to my function which makes me a table and uses the ratio of the values in this integer array to space columns along the same lines.

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);
      }
Was it helpful?

Solution

In C++ the size of an array is part of its type.* There's a special rule that allows an array declaration to deduce its size from the initializer, so you don't always have to write the type explicitly.

You can also write and use incomplete types in certain circumstances, but you can't do anything with them that requires a complete type.

So the problem here is that you're writing an incomplete type and doing something with it that requires a complete type (namely, declaring an object of that type). Adding an initializer is one way to declare the array's size and thus complete the type, which avoids the error.

If what you really want is to say "and the last field is a collection of ints," then you need to use a type that can represent that (again, arrays have a fixed number of elements). In C++ the most obvious solution is std::vector<int>. Using std::vector you can write your pseudo-code almost exactly:

oTACent.colRatios = {1, 1, 2};

Another option, which you might see but shouldn't write, is to use a pointer. C++ is defined such that you can use a pointer to an element of array similarly to an array. Since a pointer type doesn't include the array size, the same pointer type can be used with an array of any size.

* some compilers support variable length array members as an extension, where the size of the array is determined when the struct is initialized, but this isn't standard C++ and it still requires the size to be known at initialization (rather than from a later assignment, like in your pseudo code where you assign to the array). There's another extension called 'flexible arrays' where the last member can be declared without a size and then you manually allocate enough memory for the entire struct plus however large you want the array to be.

OTHER TIPS

The size of the array must be known at declaration time, since it's part its type. So you should change it to something like:

int colRatios[3];

Also, assigning to an array doesn't work the way you're attempting it:

oTACent.colRatios = [1, 1, 2];

There's no such syntax in C++. If you want to easily assign values like that, you can use C++11 and an std::vector:

std::vector<int> colRatios;
// ...
oTACent.colRatios = {1, 1, 2};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top