C ++: использование класса с явным перегруженным оператором bool - PullRequest
0 голосов
/ 23 апреля 2020

Контекст:

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

class MyBool{

    private:
    bool value_ = false;

    // Nice API and logic to set the interal value_ to true or false...

    public: 
    explicit operator bool() const {
        return value_;
    };

};

С https://en.cppreference.com/w/cpp/language/implicit_conversion, раздел «Контекстные преобразования», это работает в:

  • управляющем выражении if, while, для;
  • операнды встроенных логических операторов!, && и ||;
  • первый операнд условного оператора?:;
  • предикат в объявлении static_assert;
  • выражение в спецификаторе noexcept;

Что объясняет, почему я получаю ошибки при попытке использовать его другими способами, например:

MyBool x;  
///...
bool y = x; // --> error: cannot convert ‘MyBool’ to ‘bool’ in initialization 
// or:
bool z; 
z = x;      // --> error: cannot convert ‘MyBool’ to ‘bool’ in assignment

// Or returning from a function:
bool func(...){
     MyBool x;
     // ...
     return x; // --> error: cannot convert ‘MyBool’ to ‘bool’ in return
}

// Or in Gtests, like:
MyBool x;
// ...
EXPECT_TRUE(x); // --> error: no matching function for call to ‘testing::AssertionResult::AssertionResult(MyBool)’

Если я удалил явное ключевое слово, некоторые проблемы возникают из-за неявных преобразований (безопасный bool idiom в pre C ++ 11: http://blog.asymptotic.co.uk/2014/03/the-safe-bool-idiom-in-c/).

В этих случаях я мог бы явным образом приведите переменную MyBool к bool, и это сработает, но для меня этот вид неоднородного использования Поражает цель перегрузки оператора, то есть: иметь возможность естественным образом использовать MyBool в качестве bool. Вместо этого я мог бы добавить функцию-член следующим образом:

bool get_value() const {
    return value_;
}

И использовать x.get_value () каждый раз, когда мне нужно «привести» к bool, даже в условиях, циклах и т. Д. c.

Вопрос : есть ли способ использовать этот класс в описанных выше случаях или некоторых из них, с изменениями только кода класса (не кода вызова), и без удалить ключевое слово явное ? (Предпочтительно на C ++ 11).

Ответы [ 2 ]

3 голосов
/ 24 апреля 2020

C ++ 20 версия удаления всех операторов преобразования, которые в свою очередь неявно преобразуются в bool:

#include <concepts>

class MyBool
{
private:
    bool value_ = false;

public: 
    explicit operator bool() const { return value_; };

    template <std::convertible_to<bool> T>
    operator T() = delete;
};
3 голосов
/ 24 апреля 2020

Похоже, вопрос в том, как (1) неявно преобразовать в bool и (2) избежать целочисленного повышения / преобразования. Удалите преобразование в int:

class MyBool
{
public: 
    operator bool() const
    {
        return value_;
    };

    operator int() const = delete;

private:
    bool value_ = false;
};

Все строки в вопросе теперь компилируются, поскольку неявное преобразование разрешено. И ни одна из проблем safe-bool не компилируется, потому что целочисленное преобразование удалено:

MyBool x;
int i = x;
x << 1;
x < 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...