Почему копирование строки не допускается?

int main()
{
   std::stringstream s1("This is my string.");
   std::stringstream s2 = s1; // error, copying not allowed
}

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

Ответ 1

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

Любые средства ЛЮБЫЕ, будь то stringstream, istream, ostream, iostream или что-то еще.

Копирование потока отключено, потому что это не имеет смысла. Очень очень важно понять, что означает поток, чтобы понять, почему копирование потока не имеет смысла. 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

Ответ 2

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

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

Ответ 3

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

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

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