Зачем мне писать "std::string", но не "std:: getline()"?

Рассмотрим этот бит кода:

#include <iostream>                                                   
#include <string>

int main()
{
  std::string str;
  std::cout << "Enter a string: \n";
  getline(std::cin, str);
}

Почему я должен использовать std:: для string, cin и cout, но не getline()? Является ли getline() не в стандартной библиотеке? На самом деле я несколько смущен, почему я не могу просто написать using namespace std; и не иметь в #include ничего в стандартной библиотеке. Спасибо заранее!

Ответ 1

Возвратите магическую автоматическую квалификацию пространства имен.

Это ошибка Эндрю Кенига *.

Он рассмотрел проблему предоставления операторов для пользовательских типов. И придумал идею решения функции в зависимости от ее аргументов. Например. с аргументом типа, определенного в пространстве имен std, компилятор смотрит (также) в пространстве имен std.

Это называется поиск Koenig или ADL, для поиска зависимых от аргументов.


Re using namespace std;.

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

Однако стандартная библиотека определяет некоторые идентификаторы, такие как distance, которые могут столкнуться с именами, которые вы используете.

Следовательно, для более серьезного кода подумайте, могут ли быть другие способы избежать подробностей. Многие программисты даже утверждают, что вы не должны использовать using namespace std; в серьезном коде. Некоторые норвежские фирмы имеют это как руководство по кодированию (я не согласен с таким абсолютным взглядом, но вы должны знать, что это там, и может быть мажоритарным представлением).

Во всяком случае:

    Никогда не помещайте using namespace std; в глобальное пространство имен в заголовке

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


Почему using не делает доступными вещи.

Многие языки программирования, такие как Java и С#, а также Ada и Modula-2 и UCSD Pascal, просто для обозначения некоторых, имеют языковую поддержку для отдельных скомпилированных модулей, где модуль состоит из функций, переменных, типы, константы, возможно больше.

В зависимости от языка модуль можно назвать "модулем" (Modula-2), "пакетом" (Ada, Java), "единицей" (Pascal), "классом" (Eiffel) и так далее.

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

Но это все, а текущая примитивная система включения текста имеет большое количество проблем, наиболее явно видимых через поддержку различных компиляторов для так называемых "предварительно скомпилированных заголовков" (не являющихся частью стандарта С++!).

Дэвид Вандевоорде работал над предложение модуля для С++.

К сожалению, он не был готов для С++ 11, но, возможно, он появится позже.

*: В комментарии Дэвид Родригес добавляет, что "на самом деле это не Андрей, он только предназначил ADL для операторов, комитет распространил это на всех функции" .суб >