ivivjcb
ivivjcb

Reputation: 218

Integer cast overload being used instead of bool cast overload

I want to check if something is valid using bool cast overload:

Menu::operator bool() const {
        bool empty = false;
        if (m_title == nullptr) {
            empty = true;
        }

        return empty;
    }

However when I used

if (Menu1) { cout << "valid"; }

It used int cast overload instead

Menu::operator int()
    {
        int choice = option(); 
        return choice;
    }

Upvotes: 4

Views: 308

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311038

It seems that the object Menu1 is not a constant object. So to call the conversion operator to bool, one conversion to const is required, while to call the conversion operator to int, no conversion to const is required.

Declare both operators as constant member functions, and make them (or at least the conversion operator to int) explicit, as it is shown in the demonstrative program below:

#include <iostream>

struct A
{
    int x = 0;

    explicit operator int() const 
    { 
        std::cout << "operator int() const is called\n";
        return x; 
    }

    explicit operator bool() const 
    { 
        std::cout << "operator bool() const is called\n";
        return x != 0; 
    }
};

int main() 
{
    A a = { 10 };

    if ( a ) std::cout << a.x << '\n';

    return 0;
}

The program output is:

operator bool() const is called
10

Upvotes: 6

pcodex
pcodex

Reputation: 1940

What you are attempting is a contextual conversion, and in such cases your conversion operator needs to be well-formed. This specific scenario is detailed on cppreference.com under "Implicit conversions" in the section titled "Contextual conversions".

In fact, for the scenario mentioned above, all you need to do is to make your conversion operators const.

The below worked for me:

class Menu
{
    int choice;
    int mtitle;

public:
    Menu(int a, int b):choice(a), mtitle(b){}

    operator bool() const {
        cout << "Calling op bool\n";
        bool empty = false;
        if (mtitle == 1) {
            empty = true;
        }

        return empty;
    }

    operator int() const
    {
        cout << "Calling op int"<<"\n";
        int choice = 2;
        return choice;
    }    
};

int main()
{    
    Menu mymenu(12, 3);

    if (mymenu)
        cout << "valid\n";
}

Alternately, if you don't want to make any changes to your code, then in your main() you can call the operator explicitly, like this:

if (mymenu.operator bool())
  cout << "Op Bool is called";

Upvotes: 1

Related Questions