Могу ли я заставить тройного оператора относиться к своему классу как к Bool?

StackOverflow https://stackoverflow.com/questions/3529449

Вопрос

Недавно я делал огромный рефакторинг, когда я менял много своего кода, чтобы вернуть логических логических, а не явный код возврата. Чтобы помочь этому рефакторингу, я решил опираться на компилятор, где это возможно, заставив его сообщить мне места, где мой код должен был быть изменен. Я сделал это, введя следующий класс (Смотрите здесь, чтобы узнать, как это работает):

///
/// Typesafe boolean class
///
class TypesafeBool
{
private:
    bool m_bValue;
    struct Bool_ { 
        int m_nValue; 
    };
    typedef int Bool_::* bool_;
    inline bool_ True() const { return &Bool_::m_nValue; }
    inline bool_ False() const { return 0; }

public:
    TypesafeBool( const bool bValue ) : m_bValue( bValue ){}
    operator bool_() const { return m_bValue ? True() : False(); }
};

Теперь вместо использования нормального bool Тип как тип возврата, я использовал этот класс, что означало, что я больше не мог составить что -то подобное:

TypesafeBool SomeFunction();
long result = SomeFunction(); // error

Отлично: это сделало рефакторинг управляемой на огромной кодовой базе, позволив компилятору сделать для меня много тяжелой работы. Итак, теперь я закончил рефакторинг и мне очень хотел бы держать этот класс и продолжать использовать его, так как он обеспечивает дополнительный уровень безопасности, который встроенный bool Тип этого не делает.

Однако есть одна «проблема», которая мешает мне сделать это. На данный момент мы активно используем тройной оператор В нашем коде, и проблема в том, что он не совместим с этим новым классом без явных актеров:

TypesafeBool result = ( 1 == 2 ? SomeFunction() : false ); // error: different types used
TypesafeBool result = ( 1 == 2 ? SomeFunction() : (TypesafeBool)false );

Если бы я мог «решить» эту проблему, чтобы я мог использовать свой класс бесшовным образом, я бы, вероятно, продолжил его по всей базе кодовой. Кто -нибудь знает о решении этой проблемы? Или просто невозможно сделать то, что я хочу?

Это было полезно?

Решение

      class CCastableToBool
      {  
      public:
         // ...
         operator bool() const
         {  
           //...
           {
              return true;
           } 
           //...
           return false;
         }  
      private:
         // ...
      }; 

Но будьте осторожны, в C ++ считается действительно опасным иметь класс, который можно поднять в Bool. Вы предупреждены :-)

Вы можете прочитать это там, Safebool

Вы должны явно вызовать typesafebool :: true () во всех ваших тестовых тестах.

TypesafeBool result = ( 1 == 2 ? SomeFunction().True() : false );

Другие советы

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

Это означает, что если один из операндов является Typesafebool, то другой должен быть тоже.

Теперь проблема, которую вы действительно пытаетесь решить, была решена раньше. Хитрость не предоставляет класс; Вместо этого используйте Typedef. Смотрите, например Безопасная лопатка.

Я не знаю о беспроблемной манере, у тройного оператора есть некоторые ограничения на его использование ...

Однако почему бы вам не определить две константы?

TypesafeBool const True = TypesafeBool(true);
TypesafeBool const False = TypesafeBool(false);

А потом:

TypesafeBool result = ( 1 == 2 ? SomeFunction() : False );

Конечно, это немного неортодоксально, так как я играю на капитализацию, чтобы избежать повторного использования зарезервированного слова :)

Возможна ли сделать конструктор Typesafebool явным? Конечно, теперь использование должно быть

TypesafeBool result( 1 == 2 ? b : false );

Не могли бы вы использовать оператора назначения, который принимает в качестве внешнего аргумента, а также тот, который принимает типов? Это может быть что -то, что можно попробовать ...

Хорошая попытка, но если ваша кодовая база велико, вам, вероятно, лучше использовать статический шахтер, такой как PC-Lint, чтобы найти неявные преобразования Bool <--> int.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top