CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    [RESOLVED] How to implement Iterator into my Container

    Hi there I decide to create a personalised Container for some specific reason and now I would like to implement an Iterator that will basically allow me to iterate over the elements of the container.
    I looked into the following website in order to get an example, but I end in trouble when I tried to get elements out of the container in their initial format.
    http://universalvoid.blogspot.com/20...or-in-stl.html

    In order to be clear I will first tell what exactly I would like to do! I want to add some elements to my container then to transverse it using an Iterator. So basically I would like to make the following code to work:
    Code:
           Set teste;
    	for(int i=0; i<5; i++)
    		teste.add(i);
    		
    	Set::Iter r = teste.begin();
    	for(; r != teste.end(); ++r) {
    		int result = (*r);
    		cout << result << " ";
    	}
    	cout << endl;
    But I am getting the following error regarding the int result = (*r); line:
    -error: invalid conversion from ‘const Set*’ to ‘int’

    If I substitute int with const void* the error goes away! What I would like to achieve is to be able to cast the pointer (*rt) to int , which is not possible using my current implementation.

    Can someone have a look at my Iterator implementation and suggest some changes that would solve this problem?
    In the following two files is my Container and Iterator implementation!

    Set.hpp - the nested class Iter it is my Iterator implementation.
    Code:
    #ifndef SET_HPP_
    #define SET_HPP_
    
    #include <iostream>
    #include <list>
    #include <assert.h>
    
    using std::list;
    
    class Set
    {
    	unsigned int _size_;
    	list <int> s;			// Set of elements
    	list <int> newlist();	// private function
    	
    public:
    	Set();
    	virtual ~Set();
    	Set(const Set&);
    	friend std::ostream& operator << (std::ostream&, const Set&);
    	
    	int size();
    	int pop();
    	void add(int);
    	bool empty();
    	void clear();
    	
    	// nested class
    	class Iter {
    		friend class Set;
    		
    		typedef list <int>::iterator LI;
    		typedef list <int>::const_iterator cLI;		
    		
    		const Set* pC;
    		cLI i;
    		size_t n;
    		
    		public:
    			Iter() : pC(0), n(0) { };
    			Iter(const Set* p_, cLI i_) : pC(p_), i(i_), n(0) { };
    			Iter(const Iter & i_) : pC(i_.pC), i(i_.i), n(i_.n) { };
    			Iter& operator++() {
    				if(pC) {
    					if( ++n < (pC->_size_) ) 
    						++i;
    					else
    						pC = 0;
    					return *this;
    				}
    			}
    			
    			operator const Set* () {
    				return pC;
    			}
    			
    			Iter& operator* () {
    				return (Iter&)(*i);
    			} 
    			
    	};
    	
    	Iter begin() {
    		return Iter(this, s.begin());
    	}
    			
    	Iter end() {
    		return Iter();
    	}
    			
    	friend class Iter;
    	
    };
    
    #endif /*SET_HPP_*/
    Set.cpp - In this file there is just some functions implementation body considering only the Set class.
    Code:
    #include "Set.hpp"
    
    /*
     * Constructor
     */
    Set::Set() {
    	_size_ = 0;
    }
    
    /*
     * Terminator
     */
    Set::~Set() {
    	this->clear();
    }
    
    /*
     * Copy Constructor
     */
    Set::Set(const Set& a) {
    	_size_ = a._size_;
    	s = newlist();
    	list <int> tmp = a.s;
    	list<int>::iterator rt;
    	for(rt = tmp.begin(); rt!= tmp.end() ; rt++)
    		s.push_back( (*rt) );
    }
    
    std::ostream& operator << (std::ostream& os, const Set& f) {
    	
    	list<int> tmp = f.s;
    	list<int>::iterator rt;
    	
    	os << "Set: ";
    		
    	rt = tmp.begin();
    	for( rt = tmp.begin(); rt != tmp.end(); rt++ )
    		os << (*rt) << " ";
    	os << "Size: " << f._size_; 
    	os << std::endl;
    	
    	return os;
    }
    
    list <int> Set::newlist() {
    	list <int> p;
    	return p;
    }
    
    int Set::size() {
    	return _size_;
    }
    
    int Set::pop() {
    	assert( _size_ > 0 );
    	
    	int value = 0; 
    	
    	list<int>::iterator rt;
    	rt = s.begin();
    	
    	value = (*rt);
    	s.pop_front();
    	
    	_size_--;
    	return value;
    }
    
    void Set::add(int c) {
    	s.push_back(c);
    	_size_++;
    }
    
    bool Set::empty() {
    	return s.empty();
    }
    
    void Set::clear() {
    	s.clear();
    	_size_ = 0;
    }

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How to implement Iterator into my Container

    Quote Originally Posted by cantoma View Post
    I looked into the following website in order to get an example, but I end in trouble when I tried to get elements out of the container in their initial format.
    Please specify the compiler and compiler version you're using. There are many C++ compilers out there, and we need to know which one and what version you're using.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How to implement Iterator into my Container

    Your code when compiled on the Comeau compiler shows this:
    Code:
    #include <iostream>
    #include <list>
    #include <assert.h>
    
    using std::list;
    
    class Set
    {
    	unsigned int _size_;
    	list <int> s;			// Set of elements
    	list <int> newlist();	// private function
    	
    public:
    	Set();
    	virtual ~Set();
    	Set(const Set&);
    	friend std::ostream& operator << (std::ostream&, const Set&);
    	
    	int size();
    	int pop();
    	void add(int);
    	bool empty();
    	void clear();
    	
    	// nested class
    	class Iter {
    		friend class Set;
    		
    		typedef list <int>::iterator LI;
    		typedef list <int>::const_iterator cLI;		
    		
    		const Set* pC;
    		cLI i;
    		size_t n;
    		
    		public:
    			Iter() : pC(0), n(0) { };
    			Iter(const Set* p_, cLI i_) : pC(p_), i(i_), n(0) { };
    			Iter(const Iter & i_) : pC(i_.pC), i(i_.i), n(i_.n) { };
    			Iter& operator++() {
    				if(pC) {
    					if( ++n < (pC->_size_) ) 
    						++i;
    					else
    						pC = 0;
    					return *this;
    				}
    			}
    			
    			operator const Set* () {
    				return pC;
    			}
    			
    			Iter& operator* () {
    				return (Iter&)(*i);
    			} 
    			
    	};
    	
    	Iter begin() {
    		return Iter(this, s.begin());
    	}
    			
    	Iter end() {
    		return Iter();
    	}
    			
    	friend class Iter;
    	
    };
    
    /*
     * Constructor
     */
    Set::Set() {
    	_size_ = 0;
    }
    
    /*
     * Terminator
     */
    Set::~Set() {
    	this->clear();
    }
    
    /*
     * Copy Constructor
     */
    Set::Set(const Set& a) {
    	_size_ = a._size_;
    	s = newlist();
    	list <int> tmp = a.s;
    	list<int>::iterator rt;
    	for(rt = tmp.begin(); rt!= tmp.end() ; rt++)
    		s.push_back( (*rt) );
    }
    
    std::ostream& operator << (std::ostream& os, const Set& f) {
    	
    	list<int> tmp = f.s;
    	list<int>::iterator rt;
    	
    	os << "Set: ";
    		
    	rt = tmp.begin();
    	for( rt = tmp.begin(); rt != tmp.end(); rt++ )
    		os << (*rt) << " ";
    	os << "Size: " << f._size_; 
    	os << std::endl;
    	
    	return os;
    }
    
    list <int> Set::newlist() {
    	list <int> p;
    	return p;
    }
    
    int Set::size() {
    	return _size_;
    }
    
    int Set::pop() {
    	assert( _size_ > 0 );
    	
    	int value = 0; 
    	
    	list<int>::iterator rt;
    	rt = s.begin();
    	
    	value = (*rt);
    	s.pop_front();
    	
    	_size_--;
    	return value;
    }
    
    void Set::add(int c) {
    	s.push_back(c);
    	_size_++;
    }
    
    bool Set::empty() {
    	return s.empty();
    }
    
    void Set::clear() {
    	s.clear();
    	_size_ = 0;
    }
    Code:
    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout ! 
    
    Your Comeau C/C++ test results are as follows: 
    
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 48: warning: missing return statement at end of non-void
              function "Set::Iter::operator++"
      			}
      			^
    
    
    In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link). 
    Compiled with C++0x extensions enabled.
    So if you get rid of the warning (you should fix that), the code compiles with no errors.

    That's why it's important to state the compiler that you used.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    Re: How to implement Iterator into my Container

    Quote Originally Posted by Paul McKenzie View Post
    Please specify the compiler and compiler version you're using. There are many C++ compilers out there, and we need to know which one and what version you're using.

    Regards,

    Paul McKenzie
    So first here is my main file that successful compiles:
    algo.cpp
    Code:
    #include <iostream>
    #include <list>
    #include "Set.hpp"
    
    using std::list;
    using std::cout;
    using std::endl;
    
    int main() {
    
    	Set teste;
    	for(int i=0; i<5; i++)
    		teste.add(i+1);
    		
    	Set::Iter r = teste.begin();
    	for(; r != teste.end(); ++r) {
    		const void* result = (*r);
    		cout << result << " ";
    	}
    	cout << endl;  	
    	
    	return 0;
    }
    In order to built the executable my IDE (Eclipse) invokes the following commands.
    Code:
    make -k all 
    Building file: ../algo.cpp
    Invoking: GCC C++ Compiler
    g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"algo.d" -MT"algo.d" -o"algo.o" "../algo.cpp"
    ../Set.hpp: In member function ‘Set::Iter& Set::Iter::operator++()’:
    ../Set.hpp:57: warning: control reaches end of non-void function
    Finished building: ../algo.cpp
     
    Building target: bronkerbosch
    Invoking: GCC C++ Linker
    g++  -o"bronkerbosch"  ./Set.o ./algo.o   
    Finished building target: bronkerbosch
     
    Build complete for project bronkerbosch
    My compiler version:
    Code:
    $ gcc -v
    Using built-in specs.
    Target: i486-linux-gnu
    Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
    Thread model: posix
    gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu3)

  5. #5
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    Re: How to implement Iterator into my Container

    Quote Originally Posted by Paul McKenzie View Post
    Your code when compiled on the Comeau compiler shows this:
    Code:
    #include <iostream>
    #include <list>
    #include <assert.h>
    
    using std::list;
    
    class Set
    {
    	unsigned int _size_;
    	list <int> s;			// Set of elements
    	list <int> newlist();	// private function
    	
    public:
    	Set();
    	virtual ~Set();
    	Set(const Set&);
    	friend std::ostream& operator << (std::ostream&, const Set&);
    	
    	int size();
    	int pop();
    	void add(int);
    	bool empty();
    	void clear();
    	
    	// nested class
    	class Iter {
    		friend class Set;
    		
    		typedef list <int>::iterator LI;
    		typedef list <int>::const_iterator cLI;		
    		
    		const Set* pC;
    		cLI i;
    		size_t n;
    		
    		public:
    			Iter() : pC(0), n(0) { };
    			Iter(const Set* p_, cLI i_) : pC(p_), i(i_), n(0) { };
    			Iter(const Iter & i_) : pC(i_.pC), i(i_.i), n(i_.n) { };
    			Iter& operator++() {
    				if(pC) {
    					if( ++n < (pC->_size_) ) 
    						++i;
    					else
    						pC = 0;
    					return *this;
    				}
    			}
    			
    			operator const Set* () {
    				return pC;
    			}
    			
    			Iter& operator* () {
    				return (Iter&)(*i);
    			} 
    			
    	};
    	
    	Iter begin() {
    		return Iter(this, s.begin());
    	}
    			
    	Iter end() {
    		return Iter();
    	}
    			
    	friend class Iter;
    	
    };
    
    /*
     * Constructor
     */
    Set::Set() {
    	_size_ = 0;
    }
    
    /*
     * Terminator
     */
    Set::~Set() {
    	this->clear();
    }
    
    /*
     * Copy Constructor
     */
    Set::Set(const Set& a) {
    	_size_ = a._size_;
    	s = newlist();
    	list <int> tmp = a.s;
    	list<int>::iterator rt;
    	for(rt = tmp.begin(); rt!= tmp.end() ; rt++)
    		s.push_back( (*rt) );
    }
    
    std::ostream& operator << (std::ostream& os, const Set& f) {
    	
    	list<int> tmp = f.s;
    	list<int>::iterator rt;
    	
    	os << "Set: ";
    		
    	rt = tmp.begin();
    	for( rt = tmp.begin(); rt != tmp.end(); rt++ )
    		os << (*rt) << " ";
    	os << "Size: " << f._size_; 
    	os << std::endl;
    	
    	return os;
    }
    
    list <int> Set::newlist() {
    	list <int> p;
    	return p;
    }
    
    int Set::size() {
    	return _size_;
    }
    
    int Set::pop() {
    	assert( _size_ > 0 );
    	
    	int value = 0; 
    	
    	list<int>::iterator rt;
    	rt = s.begin();
    	
    	value = (*rt);
    	s.pop_front();
    	
    	_size_--;
    	return value;
    }
    
    void Set::add(int c) {
    	s.push_back(c);
    	_size_++;
    }
    
    bool Set::empty() {
    	return s.empty();
    }
    
    void Set::clear() {
    	s.clear();
    	_size_ = 0;
    }
    Code:
    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout ! 
    
    Your Comeau C/C++ test results are as follows: 
    
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 48: warning: missing return statement at end of non-void
              function "Set::Iter::operator++"
      			}
      			^
    
    
    In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link). 
    Compiled with C++0x extensions enabled.
    So if you get rid of the warning (you should fix that), the code compiles with no errors.

    That's why it's important to state the compiler that you used.

    Regards,

    Paul McKenzie
    So Paul could you try the following main file with your compiler and see if you get similar results?!
    algo.cpp
    Code:
    #include <iostream>
    #include <list>
    #include "Set.hpp"
    
    using std::list;
    using std::cout;
    using std::endl;
    
    int main() {
    	
    	Set teste;
    	for(int i=0; i<5; i++)
    		teste.add(i+1);
    		
    	Set::Iter r = teste.begin();
    	for(; r != teste.end(); ++r) {
    		int result = (*r);
    		cout << result << " ";
    	}
    	cout << endl;  	
    	
    	return 0;
    }
    And here is what my compiler is saying:
    Code:
    make -k all 
    Building file: ../algo.cpp
    Invoking: GCC C++ Compiler
    g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"algo.d" -MT"algo.d" -o"algo.o" "../algo.cpp"
    ../algo.cpp: In function ‘int main()’:
    ../algo.cpp:155: error: invalid conversion from ‘const Set*’ to ‘int’
    make: *** [algo.o] Error 1
    make: Target `all' not remade because of errors.
    Build complete for project bronkerbosch
    So my question regarding the compiler error is "what should I change in the Iter class in order to cast the Iter pointer into an int ?!"

  6. #6
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    Re: How to implement Iterator into my Container

    Sorry the compiler that I am using is not gcc is g++ and here is the version:

    Code:
    $ g++ -v
    Using built-in specs.
    Target: i486-linux-gnu
    Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
    Thread model: posix
    gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu3)

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How to implement Iterator into my Container

    Quote Originally Posted by cantoma View Post
    So first here is my main file that successful compiles:
    One thing I forgot to tell you is that template code must be accompanied by a main() program that instantiates the template.

    The following main() program demonstrates the error:
    Code:
    #include <iostream>
    //...
    using namespace std;
    int main()
    {
            Set teste;
    	for(int i=0; i<5; i++)
    		teste.add(i);
    		
    	Set::Iter r = teste.begin();
    	for(; r != teste.end(); ++r) {
    		int result = (*r);
    		cout << result << " ";
    	}
    	cout << endl;
    }
    The errors from Comeau:
    Code:
    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout !
    
    Your Comeau C/C++ test results are as follows:
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 48: warning: missing return statement at end of non-void
              function "Set::Iter::operator++"
      			}
      			^
    
    "ComeauTest.c", line 147: error: no suitable conversion function from "Set::Iter" to
              "int" exists
      		int result = (*r);
      		             ^
    
    1 error detected in the compilation of "ComeauTest.c".
    
    In strict mode, with -tused, Compile failed
    You are dereferencing the iterator to an int. Where in your class do you specify that dereferencing the iterator returns an int? Also, it makes the code more maintainable if you give the member variable meaningful names instead of "i" or "s". Imagine if you had a program that consists of hundreds of modules -- how would you search for any instances of the members "i" and "s"?

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    Re: How to implement Iterator into my Container

    Where in your class do you specify that dereferencing the iterator returns an int?
    Could you give me an example how my class could dereferencing the iterator return as an int?

    Also, it makes the code more maintainable if you give the member variable meaningful names instead of "i" or "s". Imagine if you had a program that consists of hundreds of modules -- how would you search for any instances of the members "i" and "s"?
    You are absolutely right, I will take that in mind!

  9. #9
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    Re: How to implement Iterator into my Container

    One thing I forgot to tell you is that template code must be accompanied by a main() program that instantiates the template.
    My Iter is not a template.

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How to implement Iterator into my Container

    Sorry, my mistake -- your code is not a template.

    The problem is that you need to return the exact type, not an Iter or a reference to one. Here is the correction:
    Code:
    int& operator* () const {
    				return (int&)(*i);
    			}
    This returns a reference to the integer.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Jan 2009
    Location
    Sheffield, UK
    Posts
    20

    Re: How to implement Iterator into my Container

    Jackpot!!
    Thank a lot Paul !! That did solve my problem!
    The example code that I took into consideration from that website was prepared to work with a template.
    Maybe that was more or less the main issue.

    Best Regards,
    Joao

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured