Подтвердить что ты не робот

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

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

Итак, мне нужно написать #include <string>, чтобы код работал?

4b9b3361

Ответ 1

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

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

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

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

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

#include <iostream>

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

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

Ответ 2

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

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

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

Ответ 3

Хотя в конкретном исходном файле нет прямого появления #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 a #include <string> in header.h
    string s = "Bar";
}

Файл: source3.cc

void zoid()
{
    // Here the error; no such thing as "string", since non of the
    // previous headers had been included.
    string s = "Zoid";
}

Ответ 4

Если вы просто используете указатель/ссылку на определенный пользователем тип, тип должен быть объявлен только:

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

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

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

Ответ 5

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

Ответ 6

Даже если вы явно не включили строку, она была включена из-за другого стандартного заголовка, который вы включили. Например, вектор может содержать строку. Когда вы включаете вектор, каждая вещь из вектора будет включена в ваш файл.

Я думаю, что будущие версии Cpp должны иметь ключевое слово include_module или module; которые включают только определенный модуль из файла. Таким образом, если файл имеет 3 класса, мы включаем только тот, который нам нужен.

например
-I "../mingw/lib/include"

 module <string>

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