Reputation: 4173
I have a struct:
typedef struct
{
Qt::Key qKey;
QString strFormType;
} KeyPair;
Now I initialize KeyPair instantiations so I could use it for my Automated Test App.
KeyPair gTestMenu[] =
{
{ Qt::Key_1 , "MyForm" },
{ Qt::Key_1 , "SubForm" },
{ Qt::Key_Escape, "DesktopForm" }
};
KeyPair gBrowseMenu[] =
{
{ Qt::Key_1 , "MyForm" },
{ Qt::Key_2 , "Dialog" },
{ Qt::Key_Escape, "DesktopForm" }
};
and like 100 more instantiations....
Currently, I call a function which uses these KeyPairs.
pressKeyPairs( gTestMenu );
pressKeyPairs( gBrowseMenu );
and more calls for the rest...
I would like to put all these KeyPair instantiations in a vector so I wouldn't have to call pressKeyPairs() a hundred times... I'm a newbie in using vectors... so I tried:
std::vector<KeyPair, std::allocator<KeyPair> > vMasterList;
vMasterList.push_back( *gTestMenu );
vMasterList.push_back( *gBrowseMenu );
std::vector<KeyPair, std::allocator<KeyPair> >::iterator iKeys;
for(iKeys = vMasterList.begin(); iKeys != vMasterList.end(); ++iKeys)
{
pressKeyPairs(*iKeys);
}
However, this code block isn't working... :( Can somebody tell me how to properly put these KeyPairs in a vector?
Upvotes: 0
Views: 288
Reputation: 361412
You've to use insert
to populate the vector with your different arrays. Here is how you should do it.
//initialized with one array
std::vector<KeyPair> vMasterList(gTestMenu, gTestMenu + 3);
//adding more items
vMasterList.insert( vMasterList.end(), gBrowseMenu , gBrowseMenu + 3);
And then reimplement your pressKeyPair
function, so that you can use std::for_each
from <algorithm>
header file as,
//pressKeyPair will be called for each item in the list!
std::for_each(vMasterList.begin(), vMasterList.end(), pressKeyPair);
Here is how you can write the pressKeyPair
function:
void pressKeyPair(KeyPair &keyPair) //takes just one item!
{
//press key pair!
}
In my opinion, this is better design, as it doesn't need "manual" loop anymore at the calling site!
You can even call pressKeyPair
for first 5 items in the list as,
//pressKeyPair will be called for first 5 items in the list!
std::for_each(vMasterList.begin(), vMasterList.begin() + 5, pressKeyPair);
One more example:
//pressKeyPair will be called for 5 items after the first 5 items, in the list!
std::for_each(vMasterList.begin()+5, vMasterList.begin() + 10, pressKeyPair);
EDIT:
If you want to use manual loop, then you've to use this:
std::vector<KeyPair>::iterator it;
for( it = vMasterList.begin(); it != vMasterList.end(); ++it)
{
pressKeyPair(*it);
}
But I would say it's not as elegant as the approach described earlier. Remember, this assumes that the function pressKeyPair
has this signature:
void pressKeyPair(KeyPair &keyPair); //it doesn't accept array!
Upvotes: 2
Reputation: 372804
I think that the problem is that the code
vMasterList.push_back( *gTestMenu );
Only adds a single element of gTestMenu
to the vector, namely the first. The reason is that this code is equivalent to the following:
vMasterList.push_back( gTestMenu[0] );
From which I think it's a bit easier to see what's going wrong.
To fix this, you probably want to add all of the elements in gTestMenu
to the master list. You can do this using the three-parameter vector::insert
function:
vMasterList.insert(v.begin(), // Insert at the beginning
gTestMenu, // From the start of gTestMenu...
gTestMenu + kNumTests); // ... to the end of the list
Here, you'll need to specify how many tests are in gTestMenu
as kNumTests
. You can do the same for gBrowseMenu
.
By the way, you don't need to specify the allocator type in the vector
declaration if you just want to use the default std::allocator
. You can just write
std::vector<KeyPair> vMasterList;
And you'll be totally fine.
Upvotes: 2