Эффект `basic_streambuf::setbuf`

Моя проблема заключается в следующем: Martin York заявляет, что в этом, этом и этом ответе можно сделать stringstream читать из некоторого фрагмента памяти, используя basic_stringbuf::pubsetbuf как это:

char buffer[] = "123";
istringstream in;
in.rdbuf()->pubsetbuf(buffer, sizeof(buffer)); // calls basic_stringbuf::setbuf
int num;
in >> num; // reads 123

К сожалению, я перерыл весь стандарт и не смог увидеть, где он гарантированно будет работать. То, что я вижу, это просто определение реализации. На самом деле на реализацию Microsoft (может быть, на других тоже) этот вызов не влияет.

Вот похожие цитаты, которые я нашел в последнем черновике C++0x. Для basic_streambuf::setbuf [Streambuf.virt.buffer]:

1 Эффекты: Влияет на потоковую буферизацию способом, который определяется отдельно для каждого класса, полученного из basic_streambuf в этом разделе (27.8.1.4, 27.9.1.5).

2 Поведение по умолчанию: ничего не делает. Возвращает это.

Однако в производных классах поведение, по-видимому, остается определяемым реализацией. За basic_stringbuf::setbuf он говорит [stringbuf.virtuals]:

1 Эффекты: определяется реализацией, за исключением того, что setbuf(0,0) не имеет эффекта.

За basic_filebuf::setbuf он говорит [filebuf.virtuals]:

12 Эффекты: если setbuf(0,0) [...], поток становится небуферизованным. В противном случае результаты определяются реализацией. "Небуферизованный" [...]

И это все. Насколько я понимаю, действительная реализация может полностью игнорировать эти вызовы (для ненулевых параметров).

Я ошибся? Как правильно интерпретировать стандарт? Есть ли у C++98/03/0x такие же гарантии? У вас есть больше статистики о том, какие реализации вышеуказанного кода работают, а какие нет? Как basic_streambuf::setbuf предназначен для использования?

2 ответа

Решение

Я считаю, что это определено реализацией и что вы предоставили соответствующие цитаты.

Напомним, что именно об этом и говорится в стандарте COS IOStreams и локали, а не в недавней книге, которую я должен признать, в разделе под названием " Почти семантическая бесплатная функция - setbuf() ":

Функция виртуального члена setbuf() является довольно своеобразным элементом буфера потока. Его семантика в основном не определена. Для строковых буферов семантика setbuf() определяются реализацией, за исключением того, что setbuf(0, 0) определяются: если setbuf(0, 0) вызывается в потоке раньше, и в этом потоке произошел ввод / вывод, поток становится небуферизованным, что означает, что символы напрямую переносятся в файловую систему и из нее. В противном случае результаты определяются реализацией.

Тем не менее, спецификации setbuf() за basic_filebuf а также basic_stringbuf вряд ли предъявляют какие-либо требования к семантике setbuf() в других типах потокового буфера. В лучшем случае общая семантика может быть определена как устройство и, в случае пользовательских типов потоковых буферов, зависит от реализации.

Отсутствие каких-либо требований освобождает вас от переопределения setbuf() практически для любой цели и любым способом, который вписывается в предопределенный интерфейс setbuf(),

ХОРОШО. Отвод.

Потратив последние пару дней на изучение документации и внесенных предложений, стало ясно, что это может не сработать (так как это определяется реализацией).

Как вы заметили в своем описании выше:

27.5.2.4.2: 1 Эффекты: Влияет на буферизацию потока способом, который определяется отдельно для каждого класса, полученного из basic_streambuf в этом разделе (27.8.1.4, 27.9.1.5).

Эффект setbuf() действительно определяется его взаимодействием с underflow() 27.8.1.4;

Возвращает: Если входная последовательность имеет доступную позицию чтения, возвращает traits::to_int_type(*gptr()). В противном случае возвращает traits::eof(). Любой символ в базовом буфере, который был инициализирован, считается частью входной последовательности.

Также для получения большего количества символов из потока необходимо проверить 27.9.1.5 showmanyc()

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

Что для буфера stringstream означает, что он ничего не получит, так как буфер уже содержит весь поток.

Так что, хотя реализация определена, как она это делает.
Это все еще хорошо определено, как это делает.

Другие вопросы по тегам