Подтвердить что ты не робот

Почему "basic_ios:: swap" выполняет только частичный обмен?

С++ 11 §27.5.4.2/21:

void swap(basic_ios& rhs);

Эффекты: состояния обмена *this и rhs должны быть заменены, за исключением того, что rdbuf() возвращает то же значение, что и перед вызовом функции, а rhs.rdbuf() возвращает то же значение, что и ранее вызов функции.

Что такое частичная свопинг, полезная для?

Может ли это вызвать проблемы?

4b9b3361

Ответ 1

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

Смена и перенос семантики была обновлена ​​в нашей системе ввода-вывода через десять лет после ее разработки. И это было не совсем здорово.

Обратите внимание, что basic_ios::swap является защищенной функцией-членом и не существует варианта области видимости пространства имен. Таким образом, это можно вызывать только из производного класса (обычно istream/ostream). Обратите внимание, что i/o_stream::swap также защищен и не имеет варианта пространства имен. И их спецификация должна вызывать базовый класс swap, а затем заменять любые локальные данные (например, gcount в istream).

Наконец, на уровне string/filestream вы получите то, что считаете стандартным вариантом swap: public member и namespace-scope. На этом уровне у вас есть член данных string/file buffer (rdbuf) и базовый класс. swap на этом уровне просто меняет базу и элементы данных.

Сложная характеристика всего этого заключается в том, что rdbuf() вниз в базовом классе фактически является указателем самореференции к производному классу streambuf (basic_filebuf или basic_stringbuf) и , который, почему вы не хотите, чтобы базовый класс менял эти указатели саморегуляции.

Это делает базу swap странной, но каждый защищен от нее, кроме производных клиентов. И код для производного клиента swap впоследствии обманчиво выглядит просто. И на производном уровне swap становится общедоступным и ведет себя так, как ожидали его публичные клиенты.

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

Было весело. Это выглядит странно. Но это в конечном счете работает.; -)

Небольшая коррекция:

Альберто Ганеш Барбати отвечает за защиту swap на уровне i/ostream. Это был очень хороший звонок с его стороны, что я полностью пропустил свой первый проект.

Ответ 2

У меня есть только один умозрительный ответ...

Если автор предположил, что поток может использовать внутренний буфер (например, элемент данных char buffer[50]), это условие необходимо, так как очевидно, что содержимое буферов может быть заменено, но их адрес останется неизменным.

Я не знаю, действительно ли это разрешено или нет.