2013-05-12 1 views
15

Я начал изучать C++, и я прочитал книгу, в которой говорится, что я должен использовать заголовочный файл , потому что тип строки не встроен непосредственно в компилятор. Если я использую <iostream>, я могу использовать тип строки.Должен ли я использовать #include <string> у <iostream>?

Должен ли я включать заголовок <string>, когда я хочу использовать тип строки, если я включил заголовок <iostream>? Зачем? Есть ли разница?

ответ

17

Да, вы должны включить то, что используете. Не предусмотрено, что стандартные заголовки включают друг друга (за некоторыми исключениями, IIRC). Теперь он может работать, но может быть неудачным на другом компиляторе.

В вашем случае, очевидно, <iostream> включает в себя <string>, прямо или косвенно, но не полагайтесь на него.

+0

Это, вероятно, форвардная декларация строки ( содержит , которая включает в себя внедрение gcc). Я думаю, что это стандартное поведение (нужно было бы проверить стандарт, хотя), поэтому я считаю, что он может полагаться на него, когда ему не нужен полный тип. – Aleph

+0

@AnotherTest «Я могу использовать тип строки» - говорит мне, что ему нужен полный тип. Если он этого не сделает, то будет дана декларация, да. –

+0

27.5.1 заявляет, что должен включать . Для этого требуется только 'char_traits', поэтому я не уверен, должен ли компилятор также пересылать объявление' string'. Я все еще сомневаюсь, что любая реализация iostream включает весь заголовок строки. – Aleph

7

Должен ли я включать заголовок <string>, когда я хочу использовать строковый тип, если я включил заголовок <iostream>?

Да, вам нужно. Вы не можете полагаться на соответствующие заголовки (например, <string>), то есть #include d косвенно через другие заголовки (например, <iostream>), хотя это может иметь место и в некоторых реализациях.

И даже тогда, когда это может показаться на работу, это может привести к неприятностям, если не все соответствующие перегрузками некоторых операторов импортируется, или если класс вперед, объявленный в заголовке вы #include, но информация о этот класс, полученный из какого-либо другого класса, содержится только в заголовке, который не получает #include d.

См., Например, this Q&A on StackOverflow для примера таких ситуаций.

+0

[ios_base :: getloc] (http://en.cppreference.com/w/cpp/io/ios_base/getloc) возвращает значение 'std :: locale' по значению и [locale :: name] (http://en.cppreference.com/w/cpp/locale/locale/name) возвращает 'std :: string' значение, поэтому' #include 'фактически требуется для полного определения' std :: string'. Только нечлены от '' являются необязательными. – Cubbi

+0

очень хороший пункт. Я просто столкнулся с проблемой, когда какой-то код библиотеки, который мы используем, полагался на это, и когда мы обновлялись с очень старой ОС/компилятора до более новой версии, компиляция нарушалась для «без видимых причин», кроме этого. – user320781

Смежные вопросы