Эффект `basic_streambuf :: setbuf` - PullRequest
       1

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

16 голосов
/ 03 декабря 2010

Моя проблема заключается в следующем: Мартин Йорк утверждает в это , это и это ответы, которые можно сделать 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 Поведение по умолчанию: Ничего не делает .Возвращает this.

Однако в производных классах поведение, по-видимому, определяется реализацией.Для 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 ]

8 голосов
/ 07 декабря 2010

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

Для записи, это то, что Стандартные потоки IOS C ++ и локали , не совсем недавняя книгаПризнайтесь, должен сказать по этому вопросу в разделе под названием " Почти семантическая бесплатная функция - setbuf()":

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

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

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

4 голосов
/ 04 декабря 2010

OK. Отвод.

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

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

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 означает, что он ничего не получит, так как буфер уже содержит весь поток.

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

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