-
February 9th, 2009, 02:53 PM
#1
[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;
}
-
February 9th, 2009, 03:15 PM
#2
Re: How to implement Iterator into my Container
Originally Posted by cantoma
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
-
February 9th, 2009, 03:18 PM
#3
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
-
February 10th, 2009, 04:46 AM
#4
Re: How to implement Iterator into my Container
Originally Posted by Paul McKenzie
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)
-
February 10th, 2009, 05:00 AM
#5
Re: How to implement Iterator into my Container
Originally Posted by Paul McKenzie
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 ?!"
-
February 10th, 2009, 05:04 AM
#6
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)
-
February 10th, 2009, 05:12 AM
#7
Re: How to implement Iterator into my Container
Originally Posted by cantoma
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
-
February 10th, 2009, 05:27 AM
#8
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!
-
February 10th, 2009, 05:32 AM
#9
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.
-
February 10th, 2009, 05:54 AM
#10
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
-
February 10th, 2009, 06:10 AM
#11
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|