This fails in g++ but compiles in VC++ 2008. Need Help.


J

Jag

template <typename T>
vertex<T>* sgraph<T>::find_a_vertex(const vertex<T>& v) {
typename set<vertex<T> >::iterator itt = _vertices.find(v) ;
if (itt == _vertices.end()) {
return NULL ;
}
vertex<T>& sv = *itt ; //LINE X
vertex<T>* asv = &(sv) ;
return asv ;
}

LINE X
error: invalid initialization of reference of type 'vertex<int>&' from
expression of type 'const vertex<int>'

What exactly is the problem here? Thanks in advance
 
Ad

Advertisements

I

Ian Collins

template<typename T>
vertex<T>* sgraph<T>::find_a_vertex(const vertex<T>& v) {
typename set<vertex<T> >::iterator itt = _vertices.find(v) ;
if (itt == _vertices.end()) {
return NULL ;
}
vertex<T>& sv = *itt ; //LINE X
vertex<T>* asv =&(sv) ;
return asv ;
}

LINE X
error: invalid initialization of reference of type 'vertex<int>&' from
expression of type 'const vertex<int>'

What exactly is the problem here? Thanks in advance

What the compiler is telling you, a *itt is a const vertex<int>. The
contents of a std::set are immutable (if you were to change a value, the
container ordering would be wrong).
 
A

Alf P. Steinbach /Usenet

* Jag, on 11.07.2010 06:56:
template<typename T>
vertex<T>* sgraph<T>::find_a_vertex(const vertex<T>& v) {
typename set<vertex<T> >::iterator itt = _vertices.find(v) ;
if (itt == _vertices.end()) {
return NULL ;
}
vertex<T>& sv = *itt ; //LINE X
vertex<T>* asv =&(sv) ;
return asv ;
}

LINE X
error: invalid initialization of reference of type 'vertex<int>&' from
expression of type 'const vertex<int>'

What exactly is the problem here? Thanks in advance

A std::set consists of immutable objects. If you could modify an object O in a
set directly, then the set object (that contains the object O) would know
nothing about the change of O, and could wind up with two or more elements that
compared as equal. Worse, in the internal structure that's hosting the elements,
the changed element could now be in an unsorted position.

So the std::set elements are 'const'.

And hence std::set<T>::iterator is really a const_iterator.


Cheers & hth.,

- Alf
 
J

Jag

What the compiler is telling you, a *itt is a const vertex<int>.  The
contents of a std::set are immutable (if you were to change a value, the
container ordering would be wrong).

First let me thanks for the answers.
But I am not convinced with this answer:
What the compiler is telling you, a *itt is a const vertex<int>. The
contents of a std::set are immutable (if you were to change a value, the
container ordering would be wrong).

typename set<vertex<T> >::iterator itt = _vertices.find(v) ;

I am inserting an object 'vertex' in the set. The vertex class has
some field (data) that I NEVER change and some fields that I need to
modify. My comparision function in vertex class is follows:

friend bool operator < (const vertex<T>& a, const vertex<T>& b) {
return (a._data < b._data) ;
}

I was under the impression that the 'set' cares about 'constness' of
ONLY compare fields. If that is so, how come vertex class as a 'whole'
is immutable ?

Are you saying that when once we put an object in set, it is NOT
possible to change any field of the object. Please clarify this point.
If this is so, how will I modify the stored object in the set. Should
I delete and add a new one?

Thanks in advance. Please help.

Jag
 
A

Alf P. Steinbach /Usenet

* Jag, on 13.07.2010 02:50:
First let me thanks for the answers.
But I am not convinced with this answer:


typename set<vertex<T> >::iterator itt = _vertices.find(v) ;

I am inserting an object 'vertex' in the set. The vertex class has
some field (data) that I NEVER change and some fields that I need to
modify. My comparision function in vertex class is follows:

friend bool operator< (const vertex<T>& a, const vertex<T>& b) {
return (a._data< b._data) ;
}

I was under the impression that the 'set' cares about 'constness' of
ONLY compare fields. If that is so, how come vertex class as a 'whole'
is immutable ?

It has no knowledge of which fields participate in object comparisions.


Are you saying that when once we put an object in set, it is NOT
possible to change any field of the object. Please clarify this point.
Yes.



If this is so, how will I modify the stored object in the set. Should
I delete and add a new one?

Yes.


Cheers & hth.,

- Alf
 
J

Jonathan Lee

I was under the impression that the 'set' cares about 'constness' of
ONLY compare fields.

Unfortunately, your impression is incorrect. See here:
http://groups.google.ca/group/comp.lang.c++/browse_thread/thread/fd9af27d3a0cc494/288fe326b6af83a2

If that is so, how come vertex class as a 'whole' is immutable ?

std::set requires that _some_ of vertex needs to be const. Thus, all
of it has to be. That's just how const works; it doesn't have levels
of refinement.

The "mutable" keyword is at your disposal for working around this,
but in this scenario it's probably not the right way to do things.
If this is so, how will I modify the stored object in the set. Should
I delete and add a new one?

I think Leigh had a link in the other thread about how to do
this best. You could also consider using std::map instead, and
split your vertex into the indexing part and the mutable part.

--Jonathan
 
Ad

Advertisements

I

Ian Collins

First let me thanks for the answers.
But I am not convinced with this answer:


typename set<vertex<T> >::iterator itt = _vertices.find(v) ;

I am inserting an object 'vertex' in the set. The vertex class has
some field (data) that I NEVER change and some fields that I need to
modify. My comparision function in vertex class is follows:

friend bool operator< (const vertex<T>& a, const vertex<T>& b) {
return (a._data< b._data) ;
}

I was under the impression that the 'set' cares about 'constness' of
ONLY compare fields. If that is so, how come vertex class as a 'whole'
is immutable ?

Are you saying that when once we put an object in set, it is NOT
possible to change any field of the object. Please clarify this point.
If this is so, how will I modify the stored object in the set. Should
I delete and add a new one?

To quote Alf's reply (he explained it better than me):

So the std::set elements are 'const'.

And hence std::set<T>::iterator is really a const_iterator.

Deletion and reinsertion is probably the "official" technique. But up
can pull a stunt with smart pointers:

#include <iostream>
#include <set>
#include <tr1/memory.hpp>

struct Ptr : std::tr1::shared_ptr<int>
{
Ptr( int* p) : std::tr1::shared_ptr<int>(p) {}

bool operator<( const Ptr& other ) const { return (**this) < *other; }
};

typedef std::set<Ptr> Set;

int main()
{
Set set;

set.insert( Ptr( new int(1) ) );
set.insert( Ptr( new int(3) ) );
set.insert( Ptr( new int(2) ) );

for( Set::iterator i = set.begin(); i != set.end(); ++i )
std::cout << **i << std::endl;

Set::iterator i = set.begin();
++i;
**i = 42;

for( Set::iterator i = set.begin(); i != set.end(); ++i )
std::cout << **i << std::endl;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top