#c #objective-c #gcc-4.2
#c #objective-c #gcc-4.2
Вопрос:
Возможно, это глупый вопрос, но меня смущает ошибка компиляции при попытке использовать идиому safe bool во время чтения этой статьи. Ниже приведен мой код, и я указал строки, в которых я получаю ошибки в функции main().
// is OK case
class BoolVer_OK {
bool m_OK;
public:
BoolVer_OK(bool ok) : m_OK(ok){}
operator bool() { return m_OK; }
};
// Not OK Case
class BoolVer_NotOK {
bool m_notOK;
public:
BoolVer_NotOK(bool ok) : m_notOK(!ok){}
bool operator !() const{ reportexecution; return !m_notOK; }
};
main()
{
BoolVer_OK ok(true);
BoolVer_NotOK notOK(true);
ok<<1; // Line#1 is valid
notOK << 1; // Line#2: error: inavlid operand to binary expression ('BoolVer_notOK' and 'int')
return 0;
}
Почему мы не получили ошибку в #Line1, в то время как мы получаем #Line2. Оба результата приводят к логическому значению перед <<
оператором.
Ответ №1:
ok
поддерживает operator bool
, и C имеет эту приятную функциональность, называемую неявным приведением, а также продвижением, и в этом случае для оператора двоичного сдвига <<
bool
значение повышается до an int
, а затем сдвигается на 1.
Во втором случае вы не указали этот оператор, и, следовательно, нет ничего, что можно неявно преобразовать (и продвинуть) в int, и вы получите ошибку. Попробуйте вызвать !notOk
перед сдвигом, теперь есть bool, который будет повышен.
Ответ №2:
Я не думаю, что компилятор автоматически вставит вызов operator!
, а затем отменит его, чтобы получить bool
то, что вы хотите. Из того, что я вижу в предоставленной вами ссылке, они выполняют свои тесты с двойным отрицанием, !!
.
Комментарии:
1. абсолютно. использование отрицания с
notOK
последующим сдвигом работает нормально.
Ответ №3:
ok<<1; // Line#1 is valid
notOK << 1; // Line#2: error: inavlid operand to binary expression ('BoolVer_notOK' and 'int')
Это происходит потому, что ok преобразуется в bool
неявно (перегруженный оператор), тогда как notOK не имеет этого оператора.
Протестируйте следующий код:
BoolVer_OK ok(true);
BoolVer_NotOK notOK(true);
int z = ok<<1; // is valid
//notOK << 1; // error: inavlid operand to binary expression ('BoolVer_notOK' and 'int')
int x = false << 1;
return 0;
Логические значения в левой части оператора сдвига преобразуются в целые числа, а затем сдвигаются.