9

I've ran across a question I am not able to answer for myself. Also, I didn't find an answer to this on both google and here. Say, I want to "check an object for validity" in an if clause, like so:

MyClass myObject;

// [some code, if any]

if (!myObject)
{
    // [do something]
}

Let MyClass be defined something like this:

class MyClass
{
public:
    MyClass() { };
    virtual ~MyClass() { };
    bool operator!()
    {
        return !myBool;
    };
    operator bool()
    {
        return myBool;
    };
private:
    bool myBool = 0;
};

My question now is: Which one of the overloaded operators is actually used in this if clause? Either way, the result is obviously the same.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
poljpocket
  • 318
  • 1
  • 10
  • I think it will go by the path of least resistance, and call `operator!`... – StoryTeller - Unslander Monica Dec 19 '13 at 14:19
  • 2
    Don't think about overloading bool until you've read this: http://stackoverflow.com/questions/6242768/is-the-safe-bool-idiom-obsolete-in-c11 – Bathsheba Dec 19 '13 at 14:20
  • 1
    Yes, just do the `operator bool` one and make it explicit. Anyway, `operator!` requires no conversions. `operator bool` requires a user-defined conversion. – chris Dec 19 '13 at 14:21
  • @doctorlove perfectionism ftw! done :-) – poljpocket Dec 19 '13 at 14:26
  • Just a question: does it really make sense to use `operator bool()`? This is probably one of the most frequent abuses of operator overloading (including in `std::ios_base`); a member function `isValid()`, or whatever, is far clearer. – James Kanze Dec 19 '13 at 14:41
  • @JamesKanze look at the discussion with Peter below. Conversion operators are used to convert an object into any desired type. – poljpocket Dec 19 '13 at 14:43
  • You could just run it through a compiler and see what your compiler thinks it should be... – PlasmaHH Dec 19 '13 at 15:00
  • @poljpocket Who said anything different? The question is whether such a use is operator overload abuse, or whether it results in obfuscation. It's very rare for an object to be `true` or `false`, and if you wouldn't say that the object is true in everyday English, then overloading `operator bool` is abuse, and should be avoided. The fact that there is a precedent for it in the standard library doesn't make it good engineering. – James Kanze Dec 19 '13 at 15:18

2 Answers2

8

It will use operator!.

A function whose parameter types match the arguments will be chosen in preference to one that requires type conversions.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
2

You'll find that operator ! gets executed because it's the most direct resolution. If it used operator bool instead then it would have to call the conversion operator first, and then apply the ! separately to that.

As a general rule, it's a good idea to avoid that situation though. It's generally better just to define the bool conversion, because strictly speaking that's what you want your logical operators to act on, rather than MyClass directly. Defining both creates a bit of a readability problem, and is a form of redundant code duplication (which can lead to programmer error in future).

Peter Bloomfield
  • 5,578
  • 26
  • 37
  • I don't agree with the redundancy you described in the last part. `operator bool()` is a conversion operator. So a statement like `bool myTest = myObject;` without the `operator bool()` present doesn't work. – poljpocket Dec 19 '13 at 14:30
  • 1
    I think you misunderstood me. I meant that defining `operator bool` **and** `operator !` is effectively code duplication, because you're needlessly replicating the same (albeit inverted) logic. – Peter Bloomfield Dec 19 '13 at 14:32