Как преобразовать std::ostringstream в bool?

Я наткнулся на этот код.

    std::ostringstream str;
    /// (some usage)
    assert( ! str );

Что означает ostringstream при использовании в контексте bool?

Возможно, это неправильное использование, которое происходит при компиляции и запуске?


person Drew Dormann    schedule 07.05.2009    source источник


Ответы (3)


Он сообщает вам, действителен ли поток в настоящее время. Это то, что могут делать все потоки. Файловый поток, например, может быть недействительным, если файл не был открыт должным образом.

В качестве примечания: эта функциональность (проверка потока как логического значения) достигается путем перегрузки explicit operator bool в C++11 и более поздних версиях и путем перегрузки оператора приведения void* в версиях до C++. 11.

Вот ссылка, содержащая некоторые примеры того, почему поток может провал. Это не относится к строковым потокам, но применимо к ним.

Редактировать: изменил bool на void* после того, как Мартин Йорк указал на мою ошибку.

person Naaff    schedule 07.05.2009
comment
На самом деле это достигается перегрузкой оператора приведения типа void*. ЕСЛИ использовался оператор приведения типа bool, тогда поток можно было бы использовать в арифметическом контексте, и компилятор привёл бы его к типу bool и использовал значение 0/1. a void*, с другой стороны, не может использоваться в арифметическом контексте, но может использоваться в логическом контексте, поскольку указатели NULL оцениваются как ложные. Но в данном случае оператор ! используется для явного возврата логического значения. - person Martin York; 07.05.2009
comment
Что это будет означать конкретно для ostringstream? Может из памяти? - person Drew Dormann; 07.05.2009
comment
@Shmoopty: То же, что и для других потоков. Попытка прочитать целое число из символов установит некоторый бит ошибки. Посетите cplusplus.com/reference/iostream/ios/fail. - person Martin York; 07.05.2009
comment
@Martin York: я понимаю, как это может произойти с istream. Как ostringstream может попытаться прочитать целое число из символов, как вы описываете? - person Drew Dormann; 08.05.2009
comment
@Shmoopty: я не уверен, как и ostringstream может потерпеть неудачу. Нехватка памяти может сделать это, но я готов поспорить, что полная память просто приводит к исключению, а не к сбою настройки. Что ясно, так это то, что ostringstream наследуется от ios_base точно так же, как любой стандартный потоковый класс, поэтому он также наследует флаги состояния, даже если для них не так много вызовов, как в таких классах, как ofstream или istringstream. - person Naaff; 08.05.2009
comment
@Martin: на самом деле люди перегружают operator mfptr, где mfptr — это тип указателя на функцию-член, чтобы люди не пытались, например. сравнивать объекты (которые сравнивали бы указатели void). - person Alexandre C.; 17.04.2011
comment
@Alexandre C: Да, это более новая техника. Но STL была построена до того, как эта техника была (обнаружена/представлена), и поэтому она использует трюк с void*. Более новый трюк с указателем метода лучше, потому что он снижает риски при автоматическом преобразовании. - person Martin York; 18.04.2011

Для справки: ostringstream::operator void*() и ostringstream::operator!().

person Donotalo    schedule 07.05.2009

Выражение допустимо и оценивает состояние потока. Эта функция чаще используется для входных потоков:

istringstream is;
is.str( "foo" );
int x;
is >> x;

if ( ! is ) {
   cerr << "Conversion failed";
}

Я не уверен, как любая из стандартных функций потоковой передачи может испортить ostringstream, но вы, безусловно, можете написать ее самостоятельно.

person Community    schedule 07.05.2009