"Apparently" senseless syntax error in template class

This error seems to make no sense!
Here's the code (not the entire code, just the relevant parts)
The error is in line 17
In member function `bool Partition<KEY>::iguales(const std::set<KEY, std::less<_Key>, std::allocator<_CharT> >&, const std::set<KEY, std::less<_Key>, std::allocator<_CharT> >&) const':
ERROR: expected `;' before "it" ; `it' undeclared (first use this function) ;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# include <iostream>
# include <set>
# include <list>

using namespace std ;

// ~~~~~~~~~~~~~~~~
// - Class Partition
// ~~~~~~~~~~~~~~~~
template <class KEY>
class Partition {
   private:
      list< set< KEY > > lista_;
      bool iguales(const set <KEY>& a,const set <KEY>& b) const{
         bool soniguales = true;
         for (set< KEY >::iterator it=a.begin(); it != a.end(); it++){ 
            bool elementoencontrado = false; 
            for (set<KEY>::iterator jt= b.begin(); jt != b.end(); jt++)
               elementoencontrado = (elementoencontrado||((*jt)==(*it)));
            soniguales = soniguales&&elementoencontrado;
         }
         //etc..etc.. 


Thanks in advance!
Last edited on
Try to add typename before set< KEY >::iterator
Thanks!. This situation has become pretty common lately, so now I know how to deal with it.

However, when instantiating it as Particion <Estado> im getting many errors.

This is one:

conversion from `std::_List_const_iterator<std::set<Estado, std::less<Estado>, std::allocator<Estado> > >' to non-scalar type `std::_List_iterator<std::set<Estado, std::less<Estado>, std::allocator<Estado> > >' requested

In here
1
2
3
bool ex = false;
for(typename list< set<KEY> >::iterator it = lista_.begin(); it != lista_.end(); it++)
   ex = ex||iguales((*it),elem); //bool iguales(const set<KEY>& a ,const set <KEY>& b) 


no matching function for call to `std::list<std::set<Estado, std::less<Estado>, std::allocator<Estado> >, std::allocator<std::set<Estado, std::less<Estado>, std::allocator<Estado> > > >::insert(const std::set<Estado, std::less<Estado>, std::allocator<Estado> >&)'


In here

1
2
   lista_.insert(elem);  //lista_'s type is list< set<Estado> >. list and set are from STL
                         //lista_ is a private atribute of Particion <Estado> 

(Operator less < is already overloaded in Estado)
Last edited on
iguales(const set<KEY>& a ,const set <KEY>& b)

Your first param to iguales is wrong.

(*it) is type KEY
the function takes type set<KEY>


'elem' is probably KEY as well (instead of set<KEY>), but I can't tell from the code here.
 
for(typename list< set<KEY> >::iterator it = lista_.begin(); it != lista_.end(); it++)

If (*it) is KEY, and not set<KEY> ... how can I access to the sequence of set<KEY> stored in lista_? (lista_ is list< set<KEY> >)

Oh, and about insert, here's the code
1
2
3
4
5
6
7
      bool insert(const set<KEY>& elem){
         if (!existe(elem)){
            lista_.insert(elem);
            return true;
         }
         return false;
      }
Last edited on
osht! I was wrong!

I didn't realize the set was in a list. My mistake. Sorry about that.

What is elem, then?

EDIT: hrm... I don't know about this one....

EDIT2:

Ah, okay. Your first thing is trying to convert a nonconst iterator to a const iterator. Try this:

 
for(typename list< set<KEY> >::const_iterator it = lista_.begin(); it != lista_.end(); it++)


Still looking at the insert bit....
Last edited on
LOL. Neither do i!!!

EDIT: elem is set<KEY> . set<....> is from the STL
Last edited on
Oh yeah...

Insert needs to take at least 2 params:

http://cplusplus.com/reference/stl/list/insert/

1 param tells it where you want to insert. If you just want to insert it to the front of the list, use push_front() instead.
Last edited on
Yup, Disch it seems to work this way

1
2
 	
for(typename list< set<KEY> >::const_iterator it = lista_.begin(); it != lista_.end(); it++)


But.. what sense does it make? I'm modifying it in the for loop!!!
Since lista_ is const, begin() will return a const_iterator instead of a nonconst iterator. And since 'iterator' and 'const_iterator' are two entirely different types, the compiler is unable to do the converion implicitly.

Note that const_iterator is not const itself -- it means that what it points to is const. You can change the const_iterator, but you can't change what the const_iterator points to.

const_iterator is different from const iterator
Last edited on
Thanks for the list reference
1
2
3
4
5
6
7
      bool insert(const set<KEY>& elem){
         if (!existe(elem)){
            lista_.insert(lista_.end(),elem); // <- Fixed!
            return true;
         }
         return false;
      }

It works now :-D

Since lista_ is const, begin() will return a const_iterator instead of a nonconst iterator. And since 'iterator' and 'const_iterator' are two entirely different types, the compiler is unable to do the converion implicitly

Actually lista_ is not const. lista_ is a private attribute of the class Particion<Estado>. Im wondering how in earth the compiler allows me to do it++ (remember "it" is const_iterator!!)
Last edited on
lista_.push_back(elem) would work too. You only need insert if you're inserting in the middle of the list.

Actually lista_ is not const


That is strange, then. The only way I can make sense of that error is if lista_ is const. Otherwise I don't see a problem.

Unless the function itself is const... in which case 'this' (and by extension lista_) becomes const.

Im wondering how in earth the compiler allows me to do it++ (remember "it" is const!!)


it is not const. It's a const iterator. There's a difference.

It's the same thing as const int* foo vs. int* const foo

1
2
3
4
5
6
7
8
9
10
11
list<int> mylist;
mylist.push_back(5);

const iterator a = mylist.begin();
const_iterator b = mylist.begin();

*a = 10;  // okay.  We're not changing a, we're changing what it points to
++a;  // error, a is const

*b = 10;  // error, can't change what const_iterator points to
++b;  // okay.  b is not const. 

Unless the function itself is const... in which case 'this' (and by extension lista_) becomes const.


Right!. The function was const. Now everything makes sense. (plus, the example was fantastic).

I'm still receiving one more error, which is the same on all operator overloads. (excepting operator = ). Im going to show the error on operator ==
in here
1
2
3
4
5
//main.cpp
//pi_vieja and pi are both Particion <Estado>
do{
   pi_vieja = pi;
}while(!(pi==pi_vieja));


no match for 'operator==' in 'pi == pi_vieja'
candidates are: bool Particion<KEY>::operator==(const std::list<std::set<KEY, std::less<_Key>, std::allocator<_CharT> >, std::allocator<std::set<KEY, std::less<_Key>, std::allocator<_CharT> > > >&) const [with KEY = Estado]


And... i guess this is the candidate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

//This is declared within Particion<KEY>

      bool operator == (const list< set<KEY> >& l)const{
         bool soniguales = true;
         //every element of a is in b
         for (typename list< set< KEY > >::const_iterator it=lista_.begin(); it != lista_.end(); it++){ 
            bool elementoencontrado = false; 
            for (typename set<KEY>::const_iterator jt= l.lista().begin(); jt != l.lista().end(); jt++)
               elementoencontrado = (elementoencontrado||((*jt)==(*it)));
            soniguales = soniguales&&elementoencontrado;
         }
         //every element of b is in a
         if (soniguales){
            for (typename set<KEY>::const_iterator it= l.lista().begin(); it != l.lista().end(); it++){
               bool elementoencontrado = false; 
               for (typename set<KEY>::const_iterator jt= lista_.begin(); jt != lista_.begin(); jt++)
                  elementoencontrado = (elementoencontrado||((*jt)==(*it)));
               soniguales = soniguales&&elementoencontrado;
            }
         }
         return soniguales;
      }
Last edited on
if pi_vieja and pi are both Particon<Estado>, then you should have a == operator in Particon that takes another Particon:

1
2
3
4
5
6
7

template <typename T>
class Particon
{
...
  bool operator == (const Particon<T>& rhs) const
  { ... }


The == you pasted (assuming it's part of the Particon class) compares a Particon<Estado> to a list<set<KEY> > -- but not to another Particon<Estado>
Holy sh-! That was the dumbest mistake EVER!. LOL

Thanks a lot Disch!!!. You've helped me a lot.
I'm marking this as solved.
Topic archived. No new replies allowed.