Почему classы std :: fstream не принимают std :: string?

Это не вопрос дизайна, действительно, хотя это может показаться. (Ну, ладно, это вопрос дизайна). Мне интересно, почему classы C ++ std::fstream не принимают std::string в своем конструкторе или открытых методах. Все любят примеры кода:

 #include  #include  #include  int main() { std::string filename = "testfile"; std::ifstream fin; fin.open(filename.c_str()); // Works just fine. fin.close(); //fin.open(filename); // Error: no such method. //fin.close(); } 

Это позволяет мне постоянно работать с файлами. Конечно, библиотека C ++ будет использовать std::string где это возможно?

10 Solutions collect form web for “Почему classы std :: fstream не принимают std :: string?”

Приняв строку C, class std::fstream classа C ++ 03 уменьшил зависимость от std::string . Однако в C ++ 11 class std::fstream позволяет передавать std::string для своего параметра конструктора.

Теперь вы можете задаться вопросом, почему нет прозрачного преобразования из std:string C, поэтому class, который ожидает, что строка C все равно будет принимать std::string как class, ожидающий std::string может взять строку C.

Причина в том, что это приведет к циклу конверсии, что, в свою очередь, может привести к проблемам. Например, предположим, std::string будет конвертируемым в строку C, чтобы вы могли использовать std::string s с fstream s. Предположим также, что строка C преобразуется в std::string s, как и состояние в текущем стандарте. Теперь рассмотрим следующее:

 void f(std::string str1, std::string str2); void f(char* cstr1, char* cstr2); void g() { char* cstr = "abc"; std::string str = "def"; f(cstr, str); // ERROR: ambiguous } 

Поскольку вы можете преобразовать любой путь между std::string и std::string C, вызов f() может разрешить любую из двух альтернатив f() и, следовательно, является неоднозначным. Решение состоит в том, чтобы разорвать цикл преобразования, сделав одно направление преобразования явным, и это то, что STL выбрал для c_str() .

Есть несколько мест, где стандартный комитет C ++ не действительно оптимизировал взаимодействие между объектами в стандартной библиотеке.

std::string и его использование в библиотеке является одним из них.

Другим примером является std::swap . Многие контейнеры имеют функцию подкачки, но перегрузка std :: swap не предоставляется. То же самое касается std::sort .

Я надеюсь, что все эти мелочи будут исправлены в предстоящем стандарте.

Возможно, это утешение: все fstream открыли (string const &, …) рядом с open (char const *, …) в рабочем черновике стандарта C ++ 0x. (см., например, 27.8.1.6 для объявления basic_ifstream)

Поэтому, когда он будет завершен и реализован, он больше не поможет вам 🙂

Библиотека streamа IO была добавлена ​​в стандартную библиотеку C ++ до STL. Чтобы не нарушать обратную совместимость, было принято решение не модифицировать библиотеку ввода-вывода при добавлении STL, даже если это означало некоторые проблемы, подобные тем, которые вы поднимаете.

@ Бернард:
Монолиты «Unstrung». «Все для одного и для всех» могут работать для мушкетеров, но это не так хорошо работает для classных дизайнеров. Вот пример, который не является вполне образцовым, и он показывает, насколько сильно вы можете ошибиться, когда дизайн превращается в overdesign. Пример, к сожалению, взят из стандартной библиотеки рядом с вами … ~ http://www.gotw.ca/gotw/084.htm

Это несущественно, это правда. Что вы подразумеваете под большим интерфейсом std :: string? Что означает большое значение, в этом контексте – много вызовов методов? Я не увлекаюсь, меня действительно интересует.

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

Реальная проблема, я думаю, состоит в том, что библиотека C ++ состоит из трех частей; у него есть старая библиотека C, у нее есть STL, и у нее есть строки и iostreams. Несмотря на то, что были предприняты некоторые усилия для объединения различных частей (например, добавление перегрузок в библиотеку C, поскольку C ++ поддерживает перегрузку, добавление iteratorов в basic_string, добавление адаптеров iteratorа iostream), существует много несоответствий, когда вы посмотрите на детали.

Например, basic_string включает методы, которые являются ненужными дубликатами стандартных алгоритмов; различные методы поиска, возможно, можно было бы безопасно удалить. Другой пример: локали используют вместо них iteratorы raw-указатели.

C ++ вырос на более мелких машинах, чем монстры, которые мы пишем сегодня на сегодня. Назад, когда iostream был новым, многие разработчики действительно заботились о размере кода (они должны были вместить всю свою программу и данные в несколько сотен КБ). Поэтому многие не хотели втягивать «большую» библиотеку строк C ++. Многие даже не использовали библиотеку iostream по тем же причинам, размер кода.

У нас не было тысяч мегабайт оперативной памяти, чтобы выбраться так же, как сегодня. У нас обычно не было связей уровня функции, поэтому мы были во власти разработчика библиотеки, чтобы использовать множество отдельных объектных файлов или тянуть тонны невостребованного кода. Все это FUD заставило разработчиков уклониться от std :: string.

Тогда я тоже избегал std :: string. «Слишком раздутый», «слишком часто называемый malloc» и т. Д. Глупо использовать стековые буферы для строк, а затем добавлять все виды утомительного кода, чтобы убедиться, что он не переполняется.

Есть ли какой-либо class в STL, который берет строку … Я так не думаю (не мог найти в моем быстром поиске). Таким образом, это, вероятно, какое-то дизайнерское решение, что ни один class в STL не должен зависеть от какого-либо другого classа STL (который не нужен непосредственно для функциональности).

Я считаю, что об этом задумали и сделали, чтобы избежать зависимости; т.е. #include не должен принуждать к #include .

Честно говоря, это кажется совершенно несущественной проблемой. Лучший вопрос: почему интерфейс std :: string настолько велик?

В настоящее время вы можете решить эту проблему очень легко: добавьте -std=c++11 в ваш CFLAGS .

  • Что стандартная библиотека гарантирует самопереключение?
  • std :: string форматирование, подобное sprintf
  • C ++ 11 STL контейнеры и безопасность streamов
  • Проверка содержимого стандартного контейнера (std :: map) с помощью gdb
  • Почему это нормально, чтобы вернуть вектор из функции?
  • C ++ сортировка и отслеживание индексов
  • std :: sort не всегда вызывает std :: swap
  • Советы по более эффективному расширению контейнера STL STL с пользовательскими методами
  • Функции std :: string length () и size ()
  • Как взорвать вектор строк в строку (элегантный способ)
  • Нечувствительность к регистру std :: string.find ()
  • Interesting Posts

    Flash-видео не отображается в WebView для Android 3.0.1

    Как обрезать пробелы из строки Python?

    Что в терминах непрофессионала – это рекурсивная функция с использованием PHP

    Найти все файлы, которые НЕ относятся к определенному типу / расширению в папке?

    STL Rope – когда и где использовать

    jQuery: keyPress Backspace не срабатывает?

    Какие шрифты поддерживают приложения для iPhone?

    Когда регистрировать / отменять регистрацию широковещательных приемников, созданных в ходе действия?

    Как я могу заставить сжатие gzip в IIS7 работать?

    Как изменить разрешение консоли сервера Ubuntu 9.10 на VMWare?

    Открыть файлы Excel в новом окне

    Синглтоны: хороший дизайн или костыль?

    Компиляция java-программы в исполняемый файл

    как получить div для случайного перемещения по странице (используя jQuery или CSS)

    Как перенести настройки учетной записи Thunderbird на новый компьютер

    Давайте будем гением компьютера.