Почему копирование потока строк не допускается? - PullRequest
53 голосов
/ 15 мая 2011
int main()
{
   std::stringstream s1("This is my string.");
   std::stringstream s2 = s1; // error, copying not allowed
}

Я не смог найти причину, почему я не могу скопировать поток строк.не могли бы вы дать ссылку?

Ответы [ 3 ]

78 голосов
/ 16 мая 2011

Копирование ЛЮБОГО потока в C ++ отключено созданием конструктора копирования private.

Любое означает ЛЮБОЕ, будь то stringstream, istream, ostream, iostream или что-либо еще.

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

Если список / вектор / карта или какой-либо контейнер является контейнером, тогда поток - это шланг, через который данные протекают . Думайте о потоке как о каком-то канале от до , по которому вы получаете данные; труба - с одной стороны источник (отправитель), с другой - приемник (получатель). Это называется однонаправленным потоком. Существуют также двунаправленные потоки, через которые данные проходят в обоих направлениях. Так что имеет смысл делать копию такой вещи? Он не содержит никаких данных вообще. Вы получаете данные с по .

Теперь предположим, что на некоторое время, если разрешено создание копии потока, и вы создали копию из std::cin, которая фактически является входным потоком. Скажем, скопированный объект copy_cin. Теперь спросите себя: имеет ли смысл читать данные из потока copy_cin, когда те же самые данные уже прочитаны из std::cin. Нет, это не имеет смысла, потому что пользователь вводил данные только один раз, клавиатура ( или устройство ввода) генерировали электрические сигналы только один раз, и они проходили через все другие аппаратные средства и низкоуровневые API только один раз. Как ваша программа может прочитать это дважды или больше ?

Следовательно, создание копии не разрешено, но создание ссылки разрешено:

std::istream  copy_cin = std::cin; //error
std::istream & ref_cin = std::cin; //ok

Также обратите внимание, что вы можете создать другой экземпляр потока и заставить его использовать тот же базовый буфер , который используется старым потоком в настоящее время. Смотрите это: https://ideone.com/rijov

4 голосов
/ 16 мая 2011

Чтобы напрямую ответить на вопрос, вы не можете копировать, потому что конструктор копирования для класса stringstream объявлен как закрытый.

Вероятно, так было объявлено, поскольку в большинстве случаев копирование потока кажется неудобным, поэтому ни один из классов потока не имеет открытых конструкторов копирования.

3 голосов
/ 16 мая 2011

Как упоминалось выше, вы не можете копировать поток, но если вам нужно, вы можете скопировать данные:

std::stringstream from;
std::stringstream to;

std::copy(std::istream_iterator<char>(from), std::istream_iterator<char>(),
          std::ostream_iterator<char>(to));
...