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

При использовании стандартных функций C в С++ требуется ли префикс "std::"?

При использовании стандартной функции C в С++ мы должны префикс каждой функции с помощью std::?

например (имя файла: std.C):

#include <cstdio>

int main() {
  std::printf("hello\n");
  printf("hello\n");
}

Этот файл можно скомпилировать с помощью:

g++ -Wall -Werror -std=c++11 std.C

без ошибок.

мои вопросы:

  • Должны ли мы всегда размещать std:: перед всеми стандартными функциями библиотеки C, когда они используются в С++?
  • Какое основное различие между заголовочными файлами, такими как <stdio.h> и <cstdio>?
4b9b3361

Ответ 1

Библиотека С++ содержит те же определения, что и язык C библиотека, организованная в той же структуре файлов заголовков, с следующие отличия:

  • Каждый заголовочный файл имеет то же имя, что и версия на языке C, но с префиксом "c" и без расширения. Например, эквивалент С++ для файла заголовка языка C <stdlib.h> есть <cstdlib>.
  • Каждый элемент библиотеки определяется в пространстве имен std.

Тем не менее, для совместимости с C традиционные имена заголовков name.h (например, stdlib.h) также предоставляются те же определения в глобальном пространстве имен, хотя его использование устарело в С++.

(источник)

Часть std:: вызова std::printf() является стандартным способом использования имен в стандартной библиотеке, поэтому я предлагаю использовать ее.

Ответ 2

Стандартная библиотека С++ включает в себя стандартную библиотеку C (с несколькими небольшими изменениями).

Каждый заголовок C с именем типа <foo.h> имеет соответствующий заголовок С++ <cfoo>. Например, заголовок С++ <cstdio> соответствует заголовку C <stdio.h>.

Цитирование стандарта ISO С++ 2011 года, 17.6.1.2 [заголовки], пункт 4:

Однако в стандартной библиотеке С++ объявления (кроме имена, которые определены как макросы в C) находятся в области пространства имен (3.3.6) пространства имен std. Неизвестно, являются ли эти имена сначала объявляются в области глобального пространства имен, а затем вводится в пространство имен std посредством явных использования-деклараций (7.3.3).

Таким образом, для #include <cstdio> функция printf определенно может называться std::printf и необязательно может быть видна как printf в глобальном пространстве имен. (Эта опция зависит от реализации, а не от программиста.)

Конечно, вы можете ссылаться на него как на printf в рамках using namespace std.

По-моему, это несчастливо; это похоже на удобство разработчиков, а не программистов. Можно с уверенностью предположить, что printf объявляется только в пространстве имен std. Если вы используете #include <cstdio>, а затем обратитесь к printf в глобальном пространстве имен, ваш код может компилироваться сегодня и не скомпилироваться в другой реализации.

И наоборот, как устаревшая функция, стандартная библиотека С++ также включает стандартные заголовки C с их исходными именами, например <stdio.h>. Цитируя стандарт, раздел D.5 [des.c.header]:

Каждый заголовок C, каждый из которых имеет имя формы name.h, ведет себя так, как если бы каждое имя помещалось в пространство имен стандартной библиотеки на соответствующий заголовок cname помещается в глобальное пространство имен объем. Не указано, объявлены ли эти имена сначала или определенных в пространстве пространства имен (3.3.6) пространства имен std и затем вводятся в область глобального пространства имен с помощью явного Использование-декларации (7.3.3).

Таким образом, имя #include <stdio.h>, имя printf определенно отображается в глобальном пространстве имен и необязательно (опять же, это вариант реализации, а не ваш), видимый как std::printf.

Ответ 3

  • std - это пространство имен и с помощью :: (после std) вы явно используете функции пространства имен std. Теперь представьте, что вы создаете собственное пространство имен, а некоторые из созданных вами функций имеют то же имя, что и функции в пространстве имен std. Это может быть проблемой, но с помощью std:: func1 и YourNameSpace:: func1 вы предотвращаете эту проблему.
  • Посмотрите здесь. Спасибо @karma_geek