2

I'm trying to merge two sets of quartets (a class which I've defined).

Before I go into the merging, let me ask a question about operator overloading. If I want to overload the operator of a class, does it make a difference whether I do it within the class or outside the class? For instance, if I did it within the class, my function header would be

bool quartet::operator<(const quartet& other)

But if I did it outside of the class, my function header would be

bool operator<(const quartet& one, const quartet& two);

I've been switching between the two because I believe it eliminated some error in one place but created another, although I could not replicate them at the time of writing this.

OK, now onto merging. Right now the following code is working (where A,B,C, and D are defined above, and A==C)

  set<quartet> Qset;
  set<quartet> result;
  Qset.insert(A);
  Qset.insert(B);
  set<quartet> Qset2; 
  Qset2.insert(C);
  Qset2.insert(D);
  merge(Qset.begin(), Qset.end(), Qset2.begin(), Qset2.end(), inserter(result, result.end()));
  printSet(result);

So, my first question is, if I change the last parameter of merge from inserter(result, result.end()) to result.begin(), I get the compiler error:

/usr/include/c++/4.6/bits/stl_algobase.h:299:6: error: passing ‘const quartet’ as ‘this’ argument of ‘quartet& quartet::operator=(const quartet&)’ discards qualifiers [-fpermissive]
make: *** [quartet.o] Error 1

Why do I get this error? My understanding is that the last parameter of merge takes an iterator to where the elements should be merged to, so why would that not be result.begin()? Furthermore, what exactly is inserter?

More generally, I'm eventually going to be working with large, sorted sets. Would it be faster to call merge or to call set_union? What is the difference between the two?

Finally, could I not just call set2.insert(set1.begin(), set1.end()) to merge the two sets together?

Thank you

user2445455
  • 349
  • 3
  • 12
  • "If I want to overload the operator of a class, does it make a difference whether I do it within the class or outside the class?" The former (within the class) is generally preferred because it's shorter and also emphasizes that the behavior is tied to the class. – Matt Kline Jun 14 '13 at 16:50
  • @slavik262 - "generally preferred" by whom? Some reasonably heavy hitters in the C++ world say ["prefer non-member non-friend functions"](http://stackoverflow.com/questions/5989734/). – Nemo Jun 14 '13 at 16:57
  • @Nemo After reading over that, I think that you're interpreting it rather broadly. There's no way to separate relational operator overloads of a class with the class implementation, so why split them up? – Matt Kline Jun 14 '13 at 17:08

2 Answers2

2

The difference between declare the overloading operator in C++ inside the class and outside of it rely on call semantic and order of objects implied.

This call need that the left most object be a quartet type.

bool quartet::operator<(const quartet& other)

While this call, allow anything that can be converted to quartet via automatic type conversion.

bool operator<(const quartet& one, const quartet& two);

see C++ overloading conversion operator for custom type to std::string

By second question, related to error, you're getting it because you need to specify that the < operator could not modify the class. You need to specify the function as const:

bool quartet::operator<(const quartet& other) const

and the you could use insert to merge these two sets.

Community
  • 1
  • 1
Jans
  • 11,064
  • 3
  • 37
  • 45
1

You're getting that error because you need to tell the compiler that your < operator does not modify the class. You do that by declaring the member function as const:

bool quartet::operator<(const quartet& other) const

Also set2.insert(set1.begin(), set1.end()) seems like it would work just fine.

Matt Kline
  • 10,149
  • 7
  • 50
  • 87