Container for arrays of structs?


    struct Pairs
        float skew = 0.5;
        float squeeze = 0;
    Pairs kick[12] =
        {0.5, 0.5}, // pitch
        {0.5, 0.7}, // tone
        {0.3, 0.7}, // decay 
        {0.6, 0.6}, // release
        {0.6, 0.6}, // freq
        {0.5, 0.5}, // curve
        {0.3, 0.5}, // square
        {0.7, 0.4}, // lowpass
        {0.2, 0.5}, // overdrive
        {0.8, 0.6}, // noise
        {0.3, 0.7}, // warb_speed
        {0.1, 0.8}, // warb_depth

sorry, more a general C++ question perhaps, but am interested to hear any advice on the best way to do this in JUCE. 

in the above code, i have an array of structs named kick, with 12 structs inside.  This number of 12 is hardcoded, and will 100% definitely never be changed.  

my issue now is how to make one more bigger container to hold several of these struct arrays (for kick, snare, hihat, etc).  Am thinking of just putting them all in a std::vector, but perhaps there is a better way to deal with all this?  

also, if i do put them in a std::vector, what syntax do i use to initialize the vector?  Here's what i sorta guessed, but it seems unlikely to me that i have this right:

 std::vector <Pairs[]> allInstruments = { kick, snare, hihat ... (etc) };

Maybe i am just barking up completely the wrong tree here, and would be better served to use some Juce containers?




just gonna do a 3D vector. 


sorry for the noise. 


I'd use a std::vector<std::array<Pairs, 12>>

As you already seem to have found out, it's a very bad idea to mix C-style arrays with C++ containers.

Also, the above would correctly reflect that one dimension is dynamic, whereas the other is static (and be more efficient than a vector of vectors).


thanks timur, 

couldn't work my head around how to get the structs initialized, but have successfully changed from a 3D std::vector to a vector of 2D std::array's.  Should be more robust and efficient.  thanks for your suggestion. 


    const std::array <std::array <float, 2>, 12> kick =


        {0.5, 0.5}, // pitch

        {0.5, 0.7}, // tone

        {0.3, 0.7}, // decay 

        {0.6, 0.6}, // release

        {0.6, 0.6}, // freq

        {0.5, 0.5}, // curve

        {0.3, 0.5}, // square

        {0.7, 0.4}, // lowpass

        {0.2, 0.5}, // overdrive

        {0.8, 0.6}, // noise

        {0.3, 0.7}, // warb_speed

        {0.1, 0.8} // warb_depth








OK, here's another suggestion looking at your new code:

use a std::pair<float, float> instead of std::array<float, 2> !


maybe ..

#include <iostream>
#include <vector>
struct X { int a,b; };
X mystatic[] = { {1,2}, {3,4}, {5,6} };
std::vector<X> mydynamic{ {1,2}, {3,4}, {5,6} };
int main() {
    mydynamic.push_back( X{7,8} );
    for ( auto &i : mydynamic )
        std::cout << i.a; // 1357
    return 0;





Personally, when there are global constant tables, I prefer to not use dynamic containers at all, and just put them all in arrays of nicely-named structures that the compiler can bake into the binary. (Unless there are good reasons to use containers because it makes it easier to access the data)


Same topic...ish...I'm having a bear of a time figuring out the syntax fot multi dimentional juce::OwnedArrays of user defined types.


i really need to spend some time getting familiar with more stuff in the std library. Thanks timur, that is indeed a nicer suggestion. 


just to confirm here Jules, 

you are talking about using std::array for your arrays, same as timur recommended?  


No, I meant just use plain old C++ const arrays and your own structs. (But only if this is some kind of const data table)


sorry for the repeatd bad question then, but what do you mean by a plain C++ array?  you mean C style arrays with the square bracket syntax?  




If you like reading, this very useful book gives a nice overview over the C++11 standard library:

After reading it through, you will have heard at least once about all the nice stuff there is :-)


As the C++11 evangelist here, let me emphasise that std::array is also perfect for compile-time tables :-)