Connecting Tech Pros Worldwide Help | Site Map

how can I reference a member function using a SET itor

Newbie
 
Join Date: Nov 2009
Location: Fairmont WV
Posts: 5
#1: 2 Weeks Ago
Please pardon my ignorance. I'm writing a C++ STL program after not writing code for 7 years, I'm trying to invoke key_word.inc() using an iterator for a set containing key_word_T. The following is a pared down version.

Expand|Select|Wrap|Line Numbers
  1. #include <cstdlib>
  2. #include <set>
  3. #include <string>
  4. using namespace std;
  5.  
  6. class key_word
  7. {
  8. public:
  9.   string word  (void) const         { return (wordX);     }
  10.   void   inc   (void)               { ++countX;           }
  11. private:
  12.   string wordX;
  13.   int countX;
  14. }; /* class key_word */
  15.  
  16. typedef class key_word key_word_T;
  17.  
  18. class key_word_sort
  19. {
  20. public:
  21.   bool operator () (const key_word_T& leftA, const key_word_T& rightA) const
  22.   {
  23.     return (leftA.word() < rightA.word());
  24.   } /* operator () */
  25. }; /* class key_word_sort */
  26.  
  27. typedef class key_word_sort key_word_sort_T;
  28.  
  29. set <key_word_T, key_word_sort_T> global_keys; // all keywords
  30. set <key_word_T, key_word_sort_T> local_keys;  // this document's keywords
  31. pair<set<key_word_T, key_word_sort_T>::iterator, bool> global_result;
  32. pair<set<key_word_T, key_word_sort_T>::iterator, bool>  local_result;
  33. set<key_word_T, key_word_sort_T>::iterator global_itor;
  34. set<key_word_T, key_word_sort_T>::iterator  local_itor;
  35.  
  36. string one_word;
  37.  
  38. int main (int, char**)
  39. {
  40.   one_word = "$FOOBAR";
  41.  
  42.   global_result = global_keys.insert (one_word); // compiles in full code, not in example
  43.   key_word_T local_key(*global_result.first); 
  44.   local_result =  local_keys.insert (local_key);
  45.   global_itor = global_result.first;
  46.   (*global_itor).inc();  // want to invoke key_word.inc() on global_keys copy
  47.  
  48.  
  49.   return (EXIT_SUCCESS);
  50. } /* main () */
best answer - posted by newb16
It looks like dereferenced iterator is a const reference, so you can call only 'const' members with it as 'this'. I could not find proof of it in online references, but it is easily explained - if you could modify set members in some other way then insertion/deletion, it may violate their order, make them non-unique, etc.
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,148
#2: 2 Weeks Ago

re: how can I reference a member function using a SET itor


Quote:

Originally Posted by jfwfmt View Post

typedef class key_word key_word_T;

typedef class key_word_sort key_word_sort_T;

Your typedefs are unnecessary in C++ you can use the class name as the type name without the class keyword (same goes for structs unions and enums) so you can declare your variables as

Expand|Select|Wrap|Line Numbers
  1. set <key_word, key_word_sort> global_keys; // all keywords
  2. set <key_word, key_word_sort> local_keys;  // this document's keywords
  3. pair<set<key_word, key_word_sort>::iterator, bool> global_result;
  4. pair<set<key_word, key_word_sort>::iterator, bool>  local_result;
  5. set<key_word, key_word_sort>::iterator global_itor;
  6. set<key_word, key_word_sort>::iterator  local_itor;
  7.  
Talking of variables that is an awful lot of global variables you have there, I would consider that bad practice in C let alone C++.

(*global_itor).inc(); // want to invoke key_word.inc() on global_keys copy
The iterator is a pointer to your type so this should work although I would write it as

global_itor->inc(); // want to invoke key_word.inc() on global_keys copy
but the 2 syntaxes have the same meaning.

Did it produce any compiler diagnostics?
Newbie
 
Join Date: Nov 2009
Location: Fairmont WV
Posts: 5
#3: 2 Weeks Ago

re: how can I reference a member function using a SET itor


Thanks for the style suggestions

Expand|Select|Wrap|Line Numbers
  1. global_itor->inc();
and
Expand|Select|Wrap|Line Numbers
  1. (*global_itor).inc();
produce the identical error message (g++)

error:passing 'const key_word' as 'this' argument of 'void key_word::inc()' discards qualifiers
Needs Regular Fix
 
Join Date: Jul 2008
Posts: 380
#4: 2 Weeks Ago

re: how can I reference a member function using a SET itor


It looks like dereferenced iterator is a const reference, so you can call only 'const' members with it as 'this'. I could not find proof of it in online references, but it is easily explained - if you could modify set members in some other way then insertion/deletion, it may violate their order, make them non-unique, etc.
Newbie
 
Join Date: Nov 2009
Location: Fairmont WV
Posts: 5
#5: 2 Weeks Ago

re: how can I reference a member function using a SET itor


Thanks, your hint about const ness was the clue. It turns out that STL implementations differ on the const of set objects. GNU makes them const.

Meyers shows a workaround for non-key data members of the objects in the set, using a cast to alter the const ness of the reference

Expand|Select|Wrap|Line Numbers
  1. const_cast<key_word_T&>(*global_itor).inc();
is the fix

/s/ Jim WIlliams
Reply

Tags
iterator, member function, set