Рассмотрим следующее:
std::ostream out(nullptr);
Является ли это законным и четко определенным?
А если я сейчас сделаю:
out << "hello world\n";
Является ли это законным и четко определенным? Если да, то, по-видимому, это не-op рода?
Рассмотрим следующее:
std::ostream out(nullptr);
Является ли это законным и четко определенным?
А если я сейчас сделаю:
out << "hello world\n";
Является ли это законным и четко определенным? Если да, то, по-видимому, это не-op рода?
Да, это законно и четко определено для создания экземпляра этого потока. Вы можете безопасно обменять его другим потоком или дать ему новый указатель (на этот раз для существующего буфера) в более позднее время. Сама операция вывода действительно не работает.
Вот почему:
Конструкция не имеет ненулевого предварительного условия и имеет только это постусловие:
[C++11: 27.7.3.2/2]:
Постусловие:rdbuf() == sb
.
Интересно, что он явно указывает, что в sb
внутри конструктора не должно выполняться никаких операций:
[C++11: 27.7.3.2/4]:
Примечания: Не выполняет никаких операций сrdbuf()
.
Но обратите внимание также:
[C++11: 27.7.3.2/1]:
Эффекты: Создает объект классаbasic_ostream
, назначая начальные значения базовому классу, вызываяbasic_ios<charT,traits>::init(sb)
(27.5.5.2).
Этот вызов init(sb)
влияет на установку badbit
в потоке, когда sb
имеет значение NULL:
[C++11: 27.5.5.2/3]:
Постусловия: постусловия этой функции указаны в таблице 128.
[C++11: Table 128]:
[..]rdstate()
:goodbit
еслиsb
не является нулевым указателем, в противном случаеbadbit
. [..]
Операция вывода приведет к действиям, эквивалентным разыменованию нулевого указателя:
[C++11: 27.7.3.1/2]:
Две группы сигнатур функций-членов имеют общие свойства: форматированные выходные функции (или вставки) и неформатированные выходные функции. Обе группы выходных функций генерируют (или вставляют) выходные символы посредством действий, эквивалентных вызовуrdbuf()->sputc(int_type)
. Они могут использовать другие публичные членыbasic_ostream
, за исключением того, что они не должны вызывать никаких виртуальных членовrdbuf()
кромеoverflow()
,xsputn()
иsync()
.
за исключением того, что он никогда не заходит так далеко, потому что для basic_ostream::sentry
построения:
[C++11: 27.7.3.4/3]:
Если после завершения любой подготовкиos.good()
true
,ok_ == true
в противном случаеok_ == false
.
а для explicit operator basic_ostream::sentry::bool() const;
:
[C++11: 27.7.3.4/5]:
Эффекты: возвращаетok_
.
и
[C++11: 27.7.3.7/1]:
Каждая неформатированная выходная функция начинает выполнение, создавая объект классаsentry
. Если этот объект возвращаетtrue
, при преобразовании в значение типаbool
, функция пытается сгенерировать запрошенный выход. [..]
& hellip; подразумевается, что никакой выходной операции вообще не происходит, когда badbit
уже установлен.