Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to create a multi-dimensional QVector variable in header file with correct size?



  • Re: How to use QVector with double
    I know how to create QVector<QPixmap> (or QVector<double>, it doesn't matter if it is double or QPixmap the code is the same) in a header file with correct size:

    QVector<QPixmap> myPixVec = QVector<QPixmap>(5)

    This creates a QVector which can hold 5 QPixmap, but what I need is a QVector<QVector<QVector<QVector<QPixmap>>>> this variable should have a dimension of 3, 2, 2, 2 for each vector respectively. How do I create such a vector in the header file?
    The main reason I am asking this is: if I do not assign the size in the header file then I have to follow a lengthy process in my implementation file to get to the right size for my vector variable.



  • @CJha
    I don't think you can assign limiting sizes like this in a header file.

    The size is created when you assign values into the object. Which you could do in the .cpp. Why is this a header file issue for you?


  • Lifetime Qt Champion

    Simply initialize your vector properly in the ctor.



  • @JonB Because if I do not do it in header file then I have to go through a process of creating temporary QVectors to assign the right size to my variable. To assign the right size to my variable QVector<QVector<QVector<QVector<QPixmap>>>> myPixVec I have to first create a temporary QVector<QPixmap> of size 3 then assign it twice to a temporary QVector<QVector<QPixmap>> then repeat the process till I have the right size and then assign it to my myPixVec.

    It is a lengthy process and I have to create many multi-dimensional vectors like this in my application.


  • Lifetime Qt Champion

    @CJha said in How to create a multi-dimensional QVector variable in header file with correct size?:

    It is a lengthy process and I have to create many multi-dimensional vectors like this in my application.

    No, it's not. Simply use QVector::resize(). It's a simple 43-dim loop



  • @Christian-Ehrlicher Ok thanks, yes I can use resize. But still, if I can create a one-dimensional vector in my header file with a given size then is there no way to do it for a multi-dimensional vector?



  • @CJha
    I have absolutely no idea what you are saying you have to do in your most recent, it doesn't sound right at all. That's all I can say.

    Anyway, both @Christian-Ehrlicher & I are saying you don't do this in the declaration in the header, you just do whatever in the .cpp.

    QVectors don't have fixed, compile-time declaration sizes anyway, they are dynamic. Plain C arrays can have fixed sizes.



  • @JonB @Christian-Ehrlicher Thanks for your input, I know it is slightly confusing. I will try to elaborate more.
    I need a multi-dimensional vector of size 3, 2, 2, 2. To get this vector I declare a variable QVector<QVector<QVector<QVector<T>>>> my4DVec in my header file. Now if it was a one-dimensional vector, I could simply assign the size while creating it like this

    QVector<T> my1DVec = QVector<T>(5); // Assuming I need the size to be 5
    

    But what I need is a multi-dimensional vector, so why cannot I go like:

    QVector<QVector<QVector<QVector<T>>>> my4DVec = QVector<QVector<QVector<QVector<T>(3)>(2)>(2)>(2);
    

    I know the above syntax is incorrect, what I am trying to ask is that Is there any syntax like this available?

    The other option is to create the vector in header file like this:

    QVector<QVector<QVector<QVector<T>>>> my4DVec;
    

    And then in my .cpp file do this:

    my4DVec.resize(2);
    my4DVec[0].resize(2);
    my4DVec[1].resize(2);
    my4DVec[0][0].resize(2);
    my4DVec[0][1].resize(2);
    my4DVec[1][0].resize(2);
    my4DVec[1][1].resize(2);
    .
    .
    .
    

    You can see that this way of doing it takes longer and is confusing. Also, I know I can use for loop for this, but that will still be lengthy and confusing. So that's why I was asking if there is a way I could do it in header file as I do it with a one-dimensional vector.


  • Lifetime Qt Champion

    @CJha said in How to create a multi-dimensional QVector variable in header file with correct size?:

    You can see that this way of doing it takes longer and is confusing

    Again: use a loop (or 3 in your case)


  • Moderators

    To do what you want you'd need to have a vector constructor that takes parameters and passes them to the constructors of its elements. There's simply no such thing in QVector, nor in any vector implementation I know.

    The effect you want can be achieved through C++ initializer lists:

    QVector<QVector<QVector<QVector<T>>>> my4DVec {{{{{},{}},{{},{}}},{{{},{}},{{},{}}}},{{{{},{}},{{},{}}},{{{},{}},{{},{}}}}};
    

    It does what you want, but I would argue is horribly confusing to read and wouldn't pass any sane code review ;)
    Just use a loop or resize like others suggested.

    Another option, if you're not planning to resize any of the vectors, is to use an array instead. Then you could simply do:

    std::array<std::array<std::array<std::array<T, 2>, 2>, 2>, 2> my4DVec;
    

    Out of curiosity - what do you need a 4D vector of pixmaps for? Sounds extremely exotic :)



  • @Chris-Kawa Thanks for explaining it to me.

    Out of curiosity - what do you need a 4D vector of pixmaps for? Sounds extremely exotic :)

    I need to store different labels which I paint on a QWidget using QPainter. Since the labels are rotated counter-clockwise 90 degrees, I need to use a QPixmap to draw labels otherwise antialiasing doesn't work and texts look weird. I realized that if I make a new label each time update() on my QWidget is called then just the part of making a label takes ~10 ms and if I store all different types of labels in a 4D vector (the labels depends on 4 different factors) of QPixmap then I could just select the correct one from the vector and increase my update() time for the QWidget (this ~10 ms is around 20-25% of my total update() time).


  • Moderators

    @CJha still, that doesn't mean it has to be a 4D vector, make it 1 dimension and define an access function, that projects the "4d coordinates" to the 1d index.



  • @J-Hilk Thanks, yes I could do that as well.


Log in to reply