Почему пропуск «#include <string>» только иногда приводит к ошибкам компиляции?

Я начинающий с C ++. Когда я пишу код иногда я пишу#include <string> и код работает, в других случаях я не пишу#include <string> и код не работает. Но иногда это работает без#include <string>.

Так я должен написать#include <string> чтобы код работал?

 AJG8502 мар. 2012 г., 21:29
Вопрос мог бы быть лучше задан, но когда они начинают с «Я новичок в C ++», можно предположить, что они могут не совсем понять, как работает, и оставить комментарий вместо закрытого или закрытого голосования.
 Konrad Rudolph02 мар. 2012 г., 21:11
Люди, какого черта ?! Конечно это реальный, законный вопрос! Откуда берутся все отрицательные и близкие голоса? Возвращайся в кровать.
 karlphillip02 мар. 2012 г., 21:16
Как-то, на мой взгляд, этот вопрос был столь же эффективным, какthese are not the droids you are looking for.
 Konrad Rudolph02 мар. 2012 г., 21:19
@ Линус Давай.

Ответы на вопрос(5)

телем тип, тип нужно только объявить:

class my_class;
void foo(const my_class& c);

Но когда вы используете значение, компилятор должен знать размер и, соответственно, определение типа.

И имейте в виду, что стандартные заголовки могут включать другие заголовки, что не означает автоматически, что все реализации делают это, поэтому вы не можете полагаться на это.

что строка заголовка включена другими заголовками. Сама строка заголовка имеет только включает в себя. Нет определений. Таким образом, все необходимые определения, необходимые для использования строки, находятся в заголовках, включенных в строку заголовка. Эти заголовки уже могут быть включены другими заголовками. Тогда все работает. Например, заголовок ios включает stringbuf, который включает ...

Другие заголовки, которые выделать включать есть#include <string> в них.

Тем не менее, это обычно хорошая идея#include <string> непосредственно в вашем коде, даже если это не является строго необходимым для успешной сборки, в случае изменения этих «других» заголовков - например, из-за другой (или другой версии) реализации компилятора / стандартной библиотеки, платформы или даже просто конфигурации сборки.

(Конечно, это обсуждение относится к любому заголовку, а не только<string>.)

непосредственный возникновение#include <string> в конкретном исходном файле не означает, что он не был включен другим заголовочным файлом. Учти это:

Файл:header.h

#if !defined(__HEADER_H__)
#define __HEADER_H__

// more here
#include <string>
// ...and here

#endif

Файл:source1.cc

#include <string>

void foo()
{
    // No error here.
    string s = "Foo";
}

Файл:source2.cc

#include <header.h>

void bar()
{
    // Still no error, since there's a #include <string> in header.h
    string s = "Bar";
}

Файл:source3.cc

void zoid()
{
    // Here's the error; no such thing as "string", since non of the
    // previous headers had been included.
    string s = "Zoid";
}
Решение Вопроса

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

Несколько компиляторы нанесколько платформы могут нанесколько время месяца компилируется, даже если вы не включили заголовок. Такое поведение неудачно, ненадежно и не означает, что вы не должны включать заголовок.

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

Всегда включайте все необходимые заголовки. К сожалению, не существует надежной онлайн-документации, в которую нужно включать заголовки. Обратитесь к книге или официальному стандарту C ++.

Например, следующий код компилируется с моим компилятором (gcc 4.6):

#include <iostream>

int main() {
    std::string str;
}

Но если я удаляю первую строку, она больше не компилируется, хотяiostream заголовок должен быть на самом деле не связан.

 Konrad Rudolph19 июл. 2016 г., 15:44
@NathanOliver Да, теперь они строго документируют это. Предыдущие версии не делали. В настоящее время cppreference.com является моей первой ссылкой на сайт.
 Konrad Rudolph09 мар. 2013 г., 12:38
@ C.R. Это, безусловно, так, поскольку стандартные заголовки иногда используют друг друга. Например,std::pair определяется в<utility> еще естьнет реализация стандартной библиотеки, которая требует, чтобы вы включили этот заголовок, если вы уже включили<map> так как последний требуетstd::pair, То же самое верно и для других типов. Это, кстати, одна из больших слабостей системы заголовков C ++ по сравнению с правильной модульной системой.
 Siyuan Ren09 мар. 2013 г., 11:43
Любая идея, происходит ли это с файлами заголовков, кроме<string>?
 NathanOliver19 июл. 2016 г., 15:39
относительноК сожалению, не существует надежной онлайн-документации, в которую нужно включать заголовки. Вы всегда можете найти то, что используете, на cppreference.com, и он сообщит вам заголовок, в котором он находится.

Ваш ответ на вопрос