C++ : How to return the value the iterator of a set is pointing to?

29,565

Solution 1

If this: *iter is an address then this: *(*iter)is the value that *iter is pointing to.

This should work in your case:

while(iter != _subordinates.end()) 
{
   os << "      " << **iter << endl ;  // <-- returns the value which is the set
   ++iter;
}

Edit: This fixed the issue: (*iter)->name()

Solution 2

That would be **iter; one dereference for the iterator, one for the pointer the iterator refers to.

Share:
29,565
user_537
Author by

user_537

Updated on April 21, 2020

Comments

  • user_537
    user_537 about 4 years

    My return value from an iterator over a set gives the memory location instead of the value. How do I access the element the iterator is pointing to?

    I used a similar iterator loop before which worked fine, as in returning the value the iterator is pointing to (for both a deque and vector template class).

    This question is a follow up on a script I had difficulties with earlier today (C++ : adding an object to a set).

    The script now looks as follows:

    header file

    #ifndef EMPLOYEE_HH
    #define EMPLOYEE_HH
    
    #include <set>
    #include <string>
    #include <iostream>
    
    using namespace std ;
    
    class Employee {
    
    public:
      // Constructor
      Employee(const char* name, double salary) :
        _name(name),
        _salary(salary) {
      }
    
      // Accessors
      const char* name() const { 
        return _name.c_str() ;
      }
    
      double salary() const {
        return _salary ;
      }
    
      // Print functions
      void businessCard(ostream& os = cout) const {
        os << "   +--------------------+  " << endl
           << "   |  ACME Corporation  |  " << endl 
           << "   +--------------------+  " << endl
           << "   Name: " << name() << endl
           << "   Salary: " << salary() << endl ;
      }
    
    private:
      string _name ;
      double _salary ;
    
    } ;
    
    class Manager : public Employee {
    
    public:
      //Constructor
      Manager(const char* _name, double _salary):
        Employee(_name, _salary),
        _subordinates() {
      }
    
      // Accessors & modifiers
      void addSubordinate(Employee& empl) {
        _subordinates.insert(&empl);
      }
    
      const set<Employee*>& listOfSubordinates() const {
        return _subordinates;
      }
    
      void businessCard(ostream& os = cout) const {
        Employee::businessCard() ;
        os << "   Function: Manager" << endl ;
    
        set<Employee*>::iterator iter ;
        iter = _subordinates.begin() ;
    
        os << "   Subordinates:" << endl ;
        if(_subordinates.empty()==true) {
          os << "      Nobody" << endl;
        }
        while(iter!=_subordinates.end()) {
          os << "      " << *iter << endl ;  // <-- returns the memory location 
          ++iter ;
        }
    
      }
    
    private:
      set<Employee*> _subordinates ;
    } ;
    
    #endif
    

    Main script

    #include <string>
    #include <iostream>
    #include "Employee.hh"
    
    using namespace std ;
    
    int main() {
    
       Employee emp1("David", 10000) ;
       Employee emp2("Ivo", 9000) ;
       Manager mgr1("Oscar", 18000) ;   // Manager of Ivo and David
       Manager mgr2("Jo", 14000) ;
       Manager mgr3("Frank", 22000) ;  // Manager of Jo and Oscar (and Ivo and David)
    
       mgr1.addSubordinate(emp1) ;
       mgr1.addSubordinate(emp2) ;
       mgr3.addSubordinate(mgr1) ;
       mgr3.addSubordinate(mgr2) ;
    
       cout << '\n' ;
       emp1.businessCard() ;
    
       cout << '\n' ;
       emp2.businessCard() ;
    
       cout << '\n' ;
       mgr1.businessCard() ;
    
       cout << '\n' ;
       mgr2.businessCard() ;
    
       cout << '\n' ;
       mgr3.businessCard() ;
    
       cout << '\n' ;       
       return 0;
    }
    

    Any help is much appreciated.

  • Alan Stokes
    Alan Stokes about 8 years
    The parentheses are redundant.
  • Khalil Khalaf
    Khalil Khalaf about 8 years
    @alan It doesn't really matter. But I will edit it just to make your day a better day
  • user_537
    user_537 about 8 years
    To be honest I already tried this before posting the question. Since this was the most logical thing to do. However, if I use **iter the compiler gives me the error cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&' for line os << " " << **iter << endl;
  • Khalil Khalaf
    Khalil Khalaf about 8 years
    @user did you try this (*iter)->Whatever?
  • user_537
    user_537 about 8 years
    @FirstStep Using (*iter)->Whatever results in the compiler saying that class Employee has no member named 'Whatever'. I am not completely familiar with using this. I suppose I should make a member function in class Employee that returns an object when using this ?
  • Khalil Khalaf
    Khalil Khalaf about 8 years
    @user I meant use (*iter)-> then choose "whatever" you want (the compiler will suggest for you once you finish typing it)
  • user_537
    user_537 about 8 years
    I am not sure what you mean with 'the compiler will suggest for you once you finish typing it'. I tried to use for example (*iter)->employee but the compiler didn't suggest anything it just gave me the same message as with using Whatever.
  • user_537
    user_537 about 8 years
    @FirstStep I am an idiot, sorry. Using (*iter)->name() did the job. Thank you for the help!
  • Khalil Khalaf
    Khalil Khalaf about 8 years
    @user awesome. Glad we could help :) Please mark and rate the answer if you found it helpful