简体   繁体   中英

Unable to access contents of initialized struct in a map

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 gDial[] =
{
    { Qt::Key_1 , "MyForm" },
    { Qt::Key_1 , "SubForm" },
    { Qt::Key_Escape, "DesktopForm" }
};

KeyPair gIP[] =
{
    { Qt::Key_1 , "MyForm" },
    { Qt::Key_2 , "Dialog" },
    { Qt::Key_2 , "Dialog" },
    { Qt::Key_Escape, "DesktopForm" }
};
....
and like 100 more instantiations....

Currently, I call a function which uses these KeyPairs.

qDebug() << "Testing Test Menu"; 
pressKeyPairs( gDial);

qDebug() << "Testing Browse Menu"; 
pressKeyPairs( gIP);
....
and more calls like this for the rest... 

I would like to put all these KeyPair instantiations in a MAP so I wouldn't have to call pressKeyPairs() and qDebug() a hundred times... I'm a newbie in using MAPS... so I tried:

map<string,KeyPair> mMasterList;
map<string,KeyPair>::iterator it;   

mMasterList.insert( pair<string, KeyPair>("Testing Test Menu", *gDial) ); //which I know is wrong, but how?
mMasterList.insert( pair<string, KeyPair>("Testing IP Menu", *gIP) );
mMasterList.insert( pair<string, KeyPair>("IP Menu2", *gIP2) );
....

for ( it=mMasterList.begin() ; it != mMasterList.end(); it++ )
{
   qDebug() << (*it).first << endl;
   pressKeyPairs((*it).second);       
   // I don't know how to access .second ... this causes a compiler error
}

EDIT: pressKeyPairs is declared as:

template <size_t nNumOfElements> void pressKeyPairs(KeyPair (&keys)[nNumOfElements]); 

This code block isn't working... :( Can somebody tell me how to properly put these KeyPairs in a Map?

What you are doing is not that wrong after all. You are getting a compiler error just because the compiler does not know how to output your array of structs to cout, so if you just output (*it).first and iterate over the elements of (*it).second you should be fine. Note however that you somehow need to make sure you know the number of entries in each of such arrays. That can be achieved for example by always having some kind of null entry as the last one (or a convention that the escape key is always the last entry or whatever)

I think Henning's answer is the way to go.
*gDial and *gIP in your code mean gDial[0] and gIP[0] .
So, you insert only the first element of the KeyPair array into mMasterList .

Your pressKeyPairs 's declaration template<size_t nNumOfElements> void pressKeyPairs(KeyPair(&keys)[nNumOfElements]); itself is correct. It takes a reference to KeyPair array as an argument.
However, since mMasterList 's second_type is KeyPair (not KeyPair array), pressKeyPairs((*it).second) invokes type mismatch error.

How about the following ideas?

  • Making a type KeyPairArray which points to KeyPair array
  • pressKeyPairs takes a reference to KeyPairArray

For example:

struct KeyPairArray {
  size_t nNumOfElements;
  KeyPair *keys;

  template< size_t N >
  KeyPairArray( KeyPair(&k)[ N ] ) : nNumOfElements( N ), keys( k ) {}
};

// Example
void pressKeyPairs( KeyPairArray const& keys )
{
  for ( size_t i = 0;  i < keys.nNumOfElements;  ++ i ) {
    qDebug()<< keys.keys[ i ].qKey <<','<< keys.keys[ i ].strFormType <<'\n';
  }
}

int main() {
  map<string,KeyPairArray> mMasterList;
  map<string,KeyPairArray>::iterator it;
  mMasterList.insert(
    make_pair( "Testing Test Menu", KeyPairArray( gDial ) ) );

  for ( it=mMasterList.begin() ; it != mMasterList.end(); it++ ) {
    pressKeyPairs( it->second );
  }
}

Hope this helps.

Try to add Q_DECLARE_METATYPE(KeyPair) after your typedef declaration and also call qRegisterMetaType("KeyPair"); before using KeyPair struct instances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM