Установить состояние потока для сообщения об ошибке в отформатированном операторе вывода (оператор <<) - PullRequest
0 голосов
/ 15 февраля 2019

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

Например, cppreference имеет следующие примеры для перегрузки операторов << и >>.

std::ostream& operator<<(std::ostream& os, const T& obj)
{
    // write obj to stream
    return os;
}
std::istream& operator>>(std::istream& is, T& obj)
{
    // read obj from stream
    if( /* T could not be constructed */ )
        is.setstate(std::ios::failbit);
    return is;
}

Вопрос: Интересно, следует ли также устанавливать битовый бит в выходном потоке (если применимо).

Пожалуйста, рассмотрите следующий пример:

enum class enumeration
{
    ONE,
    TWO
};

std::ostream& operator<<(std::ostream& os, const enumeration& e)
{
    switch (e)
    {
        case enumeration::ONE:
            os << "1";
            break;
        case enumeration::TWO:
            os << "2";
            break;
        default: 
            os.setstate(std::ios::failbit); // <-- line in question
            break;
    }
    return os;
}

Является ли данная строка разумной или нет?(Я привожу рабочий пример здесь cpp.sh .)

В конце я задаюсь вопросом, могу ли я, должен ли я или не стоит устанавливать бит-бит для ostreams и почему.

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Просто подытожив мои выводы из комментариев (спасибо Некоторому программисту, чувак за ввод) ...

Вы смешиваете две проблемы, которые лучше разделить:

a) значениеперечисление может быть недействительным

b) потоковая передача на os может завершиться с ошибкой

Можно утверждать, что a) на самом деле не относится к перегрузке operator<<.Если вы хотите убедиться, что перечисление допустимо, то вы можете проверить это, возможно, и в других местах, а не только при потоковой передаче.На самом деле вы должны сделать это раньше, чтобы иметь возможность обнаружить ошибку как можно скорее, а не только когда она достигает пользователя / внешнего мира.С другой стороны, от макушки головы я не знаю, как вы могли бы достичь default с помощью enum с определенными границами, если только вы сознательно не пытаетесь сделать что-то не так.В этом случае вы просто получаете то, что заслуживаете.Не будь чрезмерной защитой.

Для б) вам не нужно делать ничего лишнего в вашем коде.Если

 os << "1";

произойдет сбой, то этот вызов уже установит бит сбоя для вас.

TL; DR: вам, вероятно, не нужен чек в operator<<.Если вы считаете, что вам нужен чек, то operator<< все еще не подходящее место для его установки.

0 голосов
/ 15 февраля 2019

Стандартная практика для описанного вами случая - написать некоторое представление о недопустимом значении.Обычно нет необходимости отмечать это как ошибку.Например, вы можете написать «? (42)», если появится числовое значение 42.Или, может быть, просто «42», если вы предпочитаете, чтобы можно было легко возвращать текст обратно к перечислению, используя operator >>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...