С++ "перегружает" оператор if()

Можно ли изменить поведение if() так, чтобы:

class Foo {
    int x;
};

Foo foo;
if(foo)

продолжается только в том случае, если значение x является чем-то отличным от нуля? или...

Будет ли явный пользовательский тип преобразования в int работать/будет ли это подходящим подходом? или...

Лучше ли сделать что-то вроде if(foo.getX())?

Ответ 1

Вы можете преобразовать свой объект в логическое значение, указав operator bool():

explicit operator bool() const 
{ 
    return foo.getX(); 
}

Ключевое слово explicit предотвращает неявные преобразования от Foo до bool. Например, если вы случайно положили Foo в арифметическое выражение типа foo + 1, компилятор мог обнаружить эту ошибку, если объявить operator bool() как explicit, иначе Foo будет преобразован в bool, даже если не предназначен.

В общем случае функции-члены вида

operator TypeName()

(с необязательным explicit и const классификатором) являются операторами преобразования. Он позволяет отнести ваш класс к любому типу, указанному в TypeName. В другом направлении конструкторы с одним аргументом позволяют вам использовать любой тип для вашего класса:

class Foo {
  Foo(int x);    // convert int to Foo
  operator bool() const;  // convert Foo to bool
  int x;
};

Это определяет неявные преобразования для вашего класса. Компилятор пытается применить эти преобразования, если это возможно (например, что он делает для встроенных типов данных, например 5 + 1.0). Вы можете объявить их explicit для подавления нежелательных неявных преобразований.

Ответ 2

Вы можете определить оператор для преобразования объекта в bool

class Foo
{
  int x;
public:
  operator bool() const
  {
    return x > 0;
  }
};

Но это может иметь непреднамеренные последствия из-за неявных преобразований в bool, когда вы не хотите, чтобы преобразование происходило. Например,

int x = 42 + Foo();

С++ 11 решает эту проблему, разрешая вам объявлять оператор преобразования как explicit, который затем допускает неявные преобразования в определенных контекстах, например, в инструкции if.

explicit operator bool() const // allowed in C++11

Теперь

int x = 42 + Foo();  // error, no implicit conversion to bool
int x = 42 + static_cast<bool>(Foo()); // OK, explicit conversion is allowed