2

I this post, I've seen this:

class MonitorObjectString: public MonitorObject {
    // some other declarations
    friend inline bool operator==(/*const*/ MonitorObjectString& lhs,
                                  /*const*/ MonitorObjectString& rhs)
    { return lhs.fVal==rhs.fVal; }
}

Before we can continue, THIS IS VERY IMPORTANT:

  • I am not questioning anyone's ability to code.
  • I am just wondering why someone would need non-const references in a comparison.
  • The poster of that question did not write that code.

This was just in case. This is important too:

  • I added both /*const*/s and reformatted the code.

Now, we get back to the topic:

I can't think of a sane use of the equality operator that lets you modify its by-ref arguments. Do you?

Community
  • 1
  • 1
isekaijin
  • 19,076
  • 18
  • 85
  • 153

5 Answers5

5

Most likely they forgot the const. Operator overloads should behave consistently and not perform 'out of character' actions.

As a general rule, an equality operator should never modify any of the objects it is comparing. Declaring const enforces this at the compiler level. However, it is often left out. "Const correctness" is very often overlooked in C++.

Andrew Rollings
  • 14,340
  • 7
  • 51
  • 50
5

Perhaps the classes use a form of lazy initialization. When the data is accessed, proper initialization must occur, and the data must be fetched. This may change class members.

However, lazy initialization can be formed so that modification to the class isn't necessary. This can be accomplished by using the Pimpl idiom (by a pointer to a private class) or by using the mutable keyword (not recommended!).

Community
  • 1
  • 1
strager
  • 88,763
  • 26
  • 134
  • 176
  • Or the class members that may change could be declared as `mutable`. – isekaijin Dec 19 '08 at 15:50
  • @Eduardo, C++? Could you elaborate a little please? – strager Dec 19 '08 at 15:50
  • I've never seen code in other languages that cares if your objects are constants. The only other language I know that cares about that is C, but it doesn't allow operator overloading. – isekaijin Dec 19 '08 at 15:52
  • You always prefer to have the parameters const. Principle of least surprise. If your class does something behind the scenes, for example caching, you should be using mutable to mask off those side effects. – Greg Rogers Dec 19 '08 at 15:52
  • This doesn't necessarily follow. See: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.10 – Andrew Rollings Dec 19 '08 at 18:13
  • @Eduardo, Just Googled "C++ mutable" and I was suprised! I never knew such thing existed in C++ (and I'm glad I didn't!). Still, he's asking why the parameters are non-const, not how to correct the problem. I still believe my answer (pointers) is better. =] – strager Dec 19 '08 at 19:00
  • Ignore prior comment. Answer has been edited to take it into account. – Andrew Rollings Dec 20 '08 at 02:54
  • @stranger: They're non-const because the function was badly written. Comparison functions should be pure functions, i.e. have no side effects. – rlbond Jul 16 '09 at 23:16
2

There's a more baffling problem with the issue you bring up.

If I have two MonitorObjectStrings that are already const, I can't use this equality function.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
1

There's clearly no requirement for non-const args in this case and, like you, I wouldn't think there's any general case for it either.

However, it's certainly the case that const-correctness problems can push their way up from lower levels of the code, and if you can't correct them low-down, then you might have to work around them higher up. Perhaps that's what happened here at some point?

Will Dean
  • 39,055
  • 11
  • 90
  • 118
1

If you can't use const because you're modifying operands, you're badly misusing operator overloading.

If you can't use const because the implementation calls non-const functions, you really should clean those up, or at least provide const alternatives.

If you're calling into code you can't change which doesn't use const, I'd use the const anyway, use const_cast at the deepest available point, and comment it.

As Shmoopty pointed out, the operator is a lot less useful than it should be since it can't be used on const objects, even if only one of them is const. A numeric equality operator that wouldn't support "a == 5" would violate the Law of Least Astonishment in a big way.

David Thornley
  • 56,304
  • 9
  • 91
  • 158