Почему я не могу создать std :: stack of std :: ifstreams? - PullRequest
6 голосов
/ 02 марта 2010

Почему не работает следующее:

#include <iostream>
#include <fstream>
#include <stack>

std::stack<std::ifstream> s;

-pt

Ответы [ 3 ]

10 голосов
/ 02 марта 2010

std::stack (как и все контейнеры STL) требует, чтобы его содержащийся тип был «присваиваемым». В языке STL это означает, что он должен иметь конструктор копирования и operator=. std::ifstream не имеет ни одного из них.

Вы можете себе представить, почему вы не хотите иметь возможность копировать и назначать потоки ввода / вывода; семантика того, что должно происходить при наличии двух копий одного потока, не очевидна. Должно ли чтение или запись в одну копию влиять на положение другой копии? Должно ли закрытие одного потока закрывать другой? и т.д.

Если вы хотите иметь «контейнер std::ifstream с», то, что вы действительно должны сделать, это «контейнер std::ifstream* с». Неконстантные указатели всегда назначаются. Предостережение заключается в том, что в этом случае, конечно, вы должны убедиться, что удалили указатели самостоятельно, прежде чем уничтожить контейнер, поскольку контейнер не сделает этого за вас.

2 голосов
/ 02 марта 2010

Поскольку потоки не подлежат копированию, вы можете поместить их в стандартные контейнеры.

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

У Boost есть концепция контейнеров-указателей.
Это позволяет динамически размещать объект и сохранять указатель в контейнере указателя, который затем становится владельцем объекта и дает вам доступ к динамическому объекту, как если бы это был объект (а не указатель).

Поскольку контейнер указателя становится владельцем, вам не нужно беспокоиться об удалении объекта. Контейнер сделает это.

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

0 голосов
/ 02 марта 2010

Резервное копирование Тайлер здесь (после голосования +1).

Контейнеры stl копируют все объекты, которые вы им предоставляете. Если вы хотите, вы можете справиться с этим, предоставив им специальные объекты с тщательно созданными конструкторами копирования и деструкторами со счетчиком ссылок и еще много чего.

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

...