Почему вы не должны # включать <vector>, если вы уже включили использование пространства имен std? - PullRequest
0 голосов
/ 23 мая 2019

Я изучал объектно-ориентированные вычисления, в частности итераторы и стандартные библиотеки шаблонов и т. Д.

Я не совсем понимаю, почему, если ты пишешь

std:vector<int> - //blah, a vector is created.

Однако в некоторых случаях вам нужно написать

#include <vector> //to include vector library

Почему это? Включает ли стандартная библиотека, где мы обычно пишем «используя пространство имен std» - векторную библиотеку?

Когда я удаляю файл определения #include, компьютер не может распознать мои векторные переменные.

Однако в некоторых случаях я видел, что многие люди использовали векторную функцию, фактически не объявляя ее с помощью std :: vector ???

std::vector<int>::iterator pos;
std::vector<int>coll;

это код, который используют другие люди, и он работает?

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

using namespace std;

int main() {
vector<int>::iterator pos;
vector<int>coll;
}

// это работает для меня, но я хочу понять, почему этот работает, а другой нет.

Ответы [ 6 ]

1 голос
/ 23 мая 2019

Директива using namespace std; просто говорит: «Для всего, что я знаю о в пространстве имен std *, вы можете опустить префикс std::». Но без #include <vector> (прямо или косвенно через какой-то другой #include) компилятор даже не подозревает, что std::vector существует вообще.

Заголовки дают вам объявления (и в некоторых случаях определения) различных классов и API; объявление using namespace устраняет необходимость явно указывать ссылки на них с префиксом пространства имен.

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

Для дальнейшего использования, «где мы обычно выжимаем« используя пространство имен std; »» означает, что вас учили вредным привычкам. using namespace std; не одобряется в производственном коде .

0 голосов
/ 23 мая 2019

Почему бы вам не включить , если вы уже включили использование пространства имен std

Посмотрите на этот URL: https://en.cppreference.com/w/cpp/header

Тамболее 100 файлов заголовков доступны для вашего использования.

ИМХО, путаница, которую вы испытываете, заключается в том, что эти же заголовки 100+ ТАКЖЕ доступны для авторов заголовков, и они также имеют доступ к заголовкам, обычно не публикуемым в стандарте.В результате, например, когда вы или я включаем , некоторая косвенная часть этого включения может также «вставлять» .

Я рекомендую вам не включать "using namespace std" в ваш код.Его использование не вызвало намеренное «скрытое / косвенное» включение , и, возможно, не будет в следующей реализации.

Я на g ++ v7.3.Я скоро обновлюсь до текущей версии g ++ (я думаю, 9.x?). Вы не можете полагаться на включение , если только вы явно не включите его.

это работает для меня, но я хочучтобы понять, почему это работает, а другое нет.

Просто удача ... Я думаю, что плохо, если из-за этого у тебя появилось несколько вредных привычек.


Если ваш компилятор поддерживает -std = c ++ 17 или лучше, у него есть новая функция, которая мне нравится.Новая функция позволяет сразу после включения заголовка указать, какая функция в этой библиотеке мне нужна.Это выглядит так:

#include <iostream>
using std::cout, std::cerr, std::endl, std::flush,
      std::hex, std::dec, std::cin;

#include <iomanip>
using std::setw, std::setfill;

#include <string>
using std::string, std::to_string;

#include <thread>
using std::thread, std::this_thread::sleep_for;

#include <vector>
using std::vector;

Ваши собственные библиотеки могут обрабатываться аналогично:

#ifndef                 DTB_ENG_FORMAT_HH
#include "../../bag/src/dtb_eng_format.hh"
using DTB::EngFormat_t;
#endif

#ifndef                 DTB_PPLSEM_HH
#include "../../bag/src/dtb_pplsem.hh"
using DTB::PPLSem_t;
#endif

#ifndef                 DTB_ENG_FORMAT_HH
#include "../../bag/src/dtb_eng_format.hh"
#endif

#ifndef                 DTB_ASSERT_HH
#include "../../bag/src/dtb_assert.hh"
#endif

Я пытаюсь отследить небольшой набор из них и собрать их вфайл.Я использую большие списки, когда начинаю новую работу, и тривиально удаляю «неиспользуемые» функции (когда я хочу опубликовать свои усилия).

0 голосов
/ 23 мая 2019

Во-первых, std:vector<int> - //blah, a vector is created. не будет компилироваться, потому что вы использовали одиночное двоеточие :, что означает, что std здесь - это объявление label. и имя метки не может быть vector<int>. Итак, я думаю, вы имели в виду: std::vector<int>.

Во-вторых, как вы, возможно, знаете, vector, iostream, ... - это типы библиотек, определенные в заголовках <vector>, <iotream> соответственно ... Чтобы использовать эти типы, вы должны сначала включить эти заголовки либо напрямую, либо косвенно.

namespace std в C ++ - это группа идентификаторов, которая используется для уменьшения вероятности именования коллизий. В современном C ++ все функциональные возможности стандартной библиотеки C ++ теперь определены внутри пространства имен std (сокращение от стандартного).

Посмотрите, например, на std::cout; этот идентификатор объявлен в пространстве имен std, тип которого ostream. Поэтому вам необходимо сначала включить iostream, чтобы компилятор мог видеть, что такое ostream объект, а затем сообщить компилятору, где этот объект объявлен? in namespace std. Поэтому включение только iostream недостаточно, поэтому вы либо добавляете все содержимое пространства имен std, в котором объявлено cout, либо просто указываете компилятору, где cout объявляется через его полную квалификацию:

#include <iostream> // contains output/input library types definitions
using std::cout; // ok add only cout definition to the program not the whole content of std.
using namespace std; // contains cout, cin, vector....
0 голосов
/ 23 мая 2019

Почему вы не должны #include, если вы уже включили использование пространства имен std?

Вы должны включать <vector>, только если вы используете объявления из этого заголовка.В противном случае вам не нужно включать его.Вы никогда не нуждаетесь using namespace std;.

, кажется, не совсем понимаете, почему, если вы пишете

std:vector<int> - //blah, a vector is created.

Однако, в некоторых случаяхвам нужно написать

#include <vector> //to include vector library

Вы всегда должны включать <vector>, если вы создаете std:vector<int> объектов.

Соответствует ли стандартбиблиотека, где мы обычно пишем "using namespace std" - уже включает в себя векторную библиотеку?

Нет, стандартная библиотека не использует using namespace std;.Если это произойдет, это лишит смысла использование пространства имен std.

Когда я удалю файл определения #include, компьютер не сможет распознать мои векторные переменные.

Это потому, что вы не можете объявить переменную типа, который не был определен.Определение std::vector находится в <vector>

0 голосов
/ 23 мая 2019

Векторы являются частью C ++ STL, да, но вам нужно включить заголовочный файл <vector>, чтобы иметь возможность его использовать. По той же причине вам нужно #include <string>, если вы хотите использовать строки STL. После того, как вы включили эти заголовки, вам нужно использовать идентификатор пространства имен std:: перед объявлением вектора или строки, чтобы компилятор знал, что то, что вы объявляете, является частью C ++ STL, а не встроено в «базовый» C или C ++.

В принципе, то, что делает using namespace std, это дать вам возможность отбросить квалификатор std:: перед вашим string или vector или чем-то еще. Это не рекомендуется, вот статья, кратко объясняющая, почему вы не должны ее использовать. Вместо этого, если вы хотите очистить свой код и не хотите вводить std:: каждый раз, когда хотите печатать на консоль, рассмотрите возможность импорта отдельных идентификаторов, например using namespace std::cout.

Надеюсь, это поможет.

0 голосов
/ 23 мая 2019

#include <some_file> просто заменяет директиву #include содержимым файла "some_file".

В случае #include <vector> файл "вектор" содержит определение шаблона класса vector в пространстве имен std. Чтобы объявить экземпляр класса, определение этого класса должно быть видимым для компилятора, поэтому, чтобы объявить std::vector<int> foo, вы должны #include <vector>, прямо или косвенно, #include указать другой файл, #include s.

Так почему некоторые примеры кода должны #include <vector>, а другие нет? Ну, они все делают. Некоторые могут не #include это явно, но они должны #include другой файл, который #include <vector>.

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


Оператор using namespace std; просто сообщает компилятору, что он должен искать в пространстве имен std любые неквалифицированные имена, которые он не может найти в текущем пространстве имен. Это означает, что компилятор может найти класс vector по именам vector и std::vector.

...