Используется целочисленная перегрузка приведения вместо перегрузки bool - PullRequest
4 голосов
/ 17 марта 2020

Я хочу проверить, является ли что-то действительным, используя перегрузку приведения bool:

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

        return empty;
    }

Однако, когда я использовал

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

Вместо него использовалась перегрузка приведения типа int

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

Ответы [ 2 ]

6 голосов
/ 18 марта 2020

Кажется, что объект Menu1 не является постоянным объектом. Поэтому для вызова оператора преобразования в bool требуется одно преобразование в const, в то время как для вызова оператора преобразования в int преобразование в const не требуется.

Объявите оба оператора как функции-константы и сделайте их ( или хотя бы оператор преобразования в int) explicit, как показано в демонстрационной программе ниже:

#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;
}

Выходные данные программы:

operator bool() const is called
10
1 голос
/ 18 марта 2020

То, что вы пытаетесь сделать, - это контекстное преобразование, и в таких случаях ваш оператор преобразования должен быть правильно сформирован. Этот конкретный c сценарий подробно описан на cppreference.com в разделе «Неявные преобразования» в разделе «Контекстные преобразования».

Фактически, для сценария, упомянутого выше, все, что вам нужно чтобы сделать, это сделать ваши операторы преобразования const.

Для меня работает ниже:

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";
}

В качестве альтернативы, если вы не хотите вносить какие-либо изменения в свой код, то в вашем main() вы можете явно вызвать оператор, например:

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