Почему копирование потока строк не допускается?
int main()
{
std::stringstream s1("This is my string.");
std::stringstream s2 = s1; // error, copying not allowed
}
Я не смог найти причину, почему я не могу скопировать поток строк. не могли бы вы дать ссылку?
3 ответа
Копирование ЛЮБОГО потока в C++ отключено, сделав конструктор копирования 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
Чтобы напрямую ответить на вопрос, вы не можете копировать, потому что конструктор копирования для класса stringstream объявлен как закрытый.
Вероятно, так было объявлено, потому что в большинстве случаев копирование потока кажется неудобным, поэтому ни один из классов потока не имеет открытых конструкторов копирования.
Как упоминалось выше, вы не можете копировать поток, но если вам нужно, вы можете скопировать данные:
std::stringstream from;
std::stringstream to;
std::copy(std::istream_iterator<char>(from), std::istream_iterator<char>(),
std::ostream_iterator<char>(to));