Advertisement

std::list

Started by November 06, 2000 01:00 AM
3 comments, last by Spanky 24 years, 2 months ago
Ok, I just read a bit about this. Here's what I am doing. I define a structure called texture: struct texture_t { int textID; char fileName[]; }; I also have a list of all these together. list TextureList; If I wanted to search the TextureList for the one that has a certain textID, how would I do that? I know I need an list ::iterator where; and I was reading a bit of info about the find function in but dammed if I could understand the MSDN docs on that one. Any hints? Shawn Edited by - Spanky on 11/6/00 1:03:06 AM
It works like this:

        // Some #includes here...struct texture_t {  int textID;  char fileName[0x100];  // These operators are required by list and find  texture_t& operator =(const texture_t& src) {    textID = src.textID;    strcpy(fileName,src.fileName);    return (*this);  }  bool operator ==(const texture_t& src) const {    return (textID == src.textID &&       !strcmp(fileName,src.fileName));  }};typedef list<texture_t> TextureList;TextureList texList;texture_t tx;// ...fill up the list...tx.textID = 0;strcpy(tx.fileName,"file.dat");// Look for a matchTextureList::iterator it = find(texList.begin(),  texList.end(),tx);if (it != texList.end()) {  cout << "Match found" << endl;}        


You also might want to check out the Standard Template Library Programmer's Guide.

Dormeur

Edited by - Dormeur on November 6, 2000 3:06:32 AM
Wout "Dormeur" NeirynckThe Delta Quadrant Development Page
Advertisement
Also, map might be more appropriate:
    typedef map<int, string> FileMap;FileMap textures;for (/*each texture*/){  textures.insert (FileMap::value_type (textureID, textureFileName));}// when looking for textures:  FileMap::iterator texIt = textures.find (textureID);  if (texIt != textures.end ())  {    cout << "Texture found: id = " << texIt->first <<      ", filename = " << texIt->second.c_str () << endl;  }  else  {    cout << "Texture id " << textureID << " not found" << endl;  }}    

This solution assumes that no two textures have the same ID (although two different IDs are free to have the same filename).

The difference between a map and a list is:
1) The map splits up each record between data and key, where key is what you use to search the container. Since it seems to me that your structure is really just a key/data structure, map seemed more appropriate.
2) Finding a record in a list takes linear time. Finding a record in a map takes logarithmic time.
3) Lists can be in any order. A map is always sorted by key. Since it''s sorted, the type of key you use in a map must have a compare function, but if you use a standard type or one that already has a valid less-than operator, you don''t need to do any extra work.
4) Lists can have duplicate records. Maps cannot have two records with the same key (although multimap can).
5) Lists can be combined or split in constant time (really fast). Maps have to have each element read-out and inserted into a new map (really slow).

Depending on your needs, different containers are appropriate at different times. Looks to me like a map is more appropriate for your situation above.

Also, if you only build your table of texture IDs at the beginning of the program and never change it afterward, you can just use a vector and have REALLY fast searches. You can even abandon an STL container completely, and just have an array of your texture structs. When you want to search it, use lower_bound and pass it a predicate that understands your structure. This give you a binary search with no tree overhead, which is the fasting thing out there (besides hash tables, for which there is no C++ standard container ).
Ok, I decided on using a map I think so far. Is there a way that you can use 3 things in the map? I want to have the fileName of the texture, a texture ID, and also the texture stored as well.

Another thing. When I compile, I get a crap load of warnings like this one

warning C4786: ''std::reverse_bidirectional_iterator,std::map,std::allocator >::_Kfn,std::less,std::allocator >::iter
ator,std::pair,std::pair &,std::pair *,int>'' : identifier was truncated to ''255'' characters in the debug information


anyone know how to stop those?
In VC++ 6 you disable that warning with this line:

#pragma warning(disable : 4786)

good luck. as for the 3 thing issue, it can obviously be done, but the method depends on your needs. if you need one lookup criteria to lead you to more than one piece of data, such as looking up the id and getting the name and actual object, then you simply make a structure for those 2 (or more) items ... or when it''s just exactly 2 items, you can use the std::pair template.

good luck

This topic is closed to new replies.

Advertisement