overloading *=

Sorry to bombard you guys with questions. I'm getting an error that seems to stem from overloading *= and I am stumped.

Here is the function:
1
2
3
4
void timesequals(multiset<Algebraic>& S, const Algebraic& x)
{
  multiset<Algebraic>::iterator i;
  for(i = S.begin(); i != S.end(); i++)
}


The problem seems to involve *= (which normally works fine). Its declaration is:
 
Algebraic& Algebraic::operator *=(const Algebraic& s);


Algebraic is a class I defined, presumably the definition is not relevent. Now when I compile, here is the error:

g++ -c -I. -I/opt/local/include -I/usr/local/include -g algebraic.cc
algebraic.cc: In function ‘void timesequals(std::multiset<Algebraic, std::less<Algebraic>, std::allocator<Algebraic> >&, const Algebraic&)’:
algebraic.cc:1207: error: passing ‘const Algebraic’ as ‘this’ argument of ‘Algebraic& Algebraic::operator*=(const Algebraic&)’ discards qualifiers

Line 1207 is the one the arrow is pointing to in the first code fragment.

Any idea what is wrong? The compiler seems to think S is a const...

EDIT: Probably *= is fine, but the compiler doesn't want me to access directly the elements of a multiset because it is worried I may screw up the order. Is it possible to override this behavior?
Last edited on
No, the problem is that *i is giving you a const Algebraic &, but Algebraic::operator*=() is not const (i.e. it's not guaranteed to not modify the members of *this).
What I don't understand is why dereferencing the iterator gives a const T& instead of a const T.
I get a similar error with
1
2
3
4
5
6
7
8
9
10
11
12
#include<set>

using namespace std;

int main()
{
  multiset<int> S;
  S.insert(1);
  set<int>::iterator i = S.begin();
  *i = 2;
  return 0;
}


g++ test5.cc
test5.cc: In function ‘int main()’:
test5.cc:10: error: assignment of read-only location ‘i.std::_Rb_tree_const_iterator<_Tp>::operator* [with _Tp = int]()’

Seems g++ really doesn't want you to modify elements of a set.
Now that I think about it, it makes sense, since an element in a set is both a value and a key, and changing the value of a key in a tree can cause disaster. You can can't modify the second first of an std::map<T>::iterator, either.
remove() the element you want to change and reinsert it changed.
Last edited on
Thanks, that makes sense. I thought of that but didn't want to do it since it is not efficient. Probably its just best for me to use a different container here.
Man, I totally screwed up the meaning in my previous post.
Topic archived. No new replies allowed.