При использовании заголовков C в C++, мы должны использовать функции из std:: или глобального пространства имен?
C - это не совсем подмножество C++. Таким образом, мы можем использовать большинство функций / заголовков C в C++, немного изменив имя (stdio.h
в cstdio
, stdlib.h
в cstdlib
).
Мой вопрос на самом деле является семантическим. В коде C++ (используя новейшую версию компилятора GCC) я могу вызвать printf("Hello world!);
а также std::printf("Hello world!);
и работает точно так же. И в ссылке, которую я использую, это также выглядит как std::printf("Hello world!);
,
Мой вопрос, является ли это предпочтительным для использования std::printf();
в С ++? Есть ли разница?
9 ответов
Из стандарта C++11 (выделено мое):
Заголовки стандартной библиотеки D.5 C [depr.c.headers]
- Для совместимости со стандартной библиотекой C...
- Каждый заголовок C, каждый из которых имеет имя формы name.h, ведет себя так, как будто каждое имя, помещенное в стандартное пространство имен библиотеки соответствующим заголовком cname, помещается в глобальную область пространства имен. Не определено, были ли эти имена сначала объявлены или определены в пределах области имен (3.3.6) пространства имен std, а затем введены в глобальную область имен с помощью явных объявлений using (7.3.3).
- Пример: заголовок
<cstdlib>
гарантированно обеспечивает свои объявления и определения в пространстве именstd
, Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок<stdlib.h>
несомненно, обеспечивает те же объявления и определения в глобальном пространстве имен, как и в стандарте C. Он также может предоставлять эти имена в пространстве именstd
,
Использование заголовков "name.h" не рекомендуется, они были определены как кандидаты на удаление из будущих версий.
Итак, я бы предложил включить заголовки "cname" и использовать объявления и определения из std
Пространство имен.
Если по каким-либо причинам вам придется использовать заголовки "name.h" (это устарело, см. Выше), я бы предложил использовать объявления и определения из глобального пространства имен.
Другими словами: предпочитаю
#include <cstdio>
int main() {
std::printf("Hello world\n");
}
над
#include <stdio.h>
int main() {
printf("Hello world\n");
}
<cmeow>
всегда обеспечивает ::std::purr
и может или не может предоставить ::purr
,
<meow.h>
всегда обеспечивает ::purr
и может или не может предоставить ::std::purr
,
Используйте форму, которая гарантированно будет указана в заголовке, который вы включаете.
Нет, ты в порядке в любом случае.
Первоначально предполагалось, что <___.h>
Заголовки будут версиями C, которые помещают все в глобальное пространство имен, а <c___>
заголовки будут версиями C++-ified, которые помещают все в std
Пространство имен.
На практике, однако, версии C++ также помещают все в глобальное пространство имен. И нет единого мнения, что использование std::
Версии "правильная вещь".
Так что, в основном, используйте то, что вы предпочитаете. Наиболее распространенным является, вероятно, использование стандартных функций библиотеки C в глобальном пространстве имен (printf
вместо std::printf
), но нет особых оснований считать одно "лучше" другого.
Из стандарта C++11:
Каждый заголовок C, каждый из которых имеет имя формы name.h, ведет себя так, как будто каждое имя, помещенное в стандартное пространство имен библиотеки соответствующим заголовком cname, помещается в глобальную область пространства имен. Не определено, были ли эти имена сначала объявлены или определены в пределах области имен (3.3.6) пространства имен std, а затем введены в глобальную область имен с помощью явных объявлений using (7.3.3).
Итак, если вы используете <cstdio>
можете быть уверены, что printf
будет в namespace std
и, следовательно, не в глобальном пространстве имен.
Использование глобального пространства имен создает конфликт имен. Это не C++ путь.
Поэтому я использую <cstdio>
Заголовки и советую вам сделать это.
Из моей собственной практики: использовать std::
префиксы. В противном случае один день abs
будет очень больно кусать вас, если вы используете плавающие точки.
Неквалифицированный abs
относится к функции, определенной на int
на некоторых платформах. На других это перегружено. тем не мение std::abs
всегда перегружен для всех типов.
Единственная разница в том, что в std::printf()
добавляя std::
Разрешение области действия Вы обезопасите себя от того, что кто-то напишет в будущем функцию с тем же именем, что приведет к конфликту пространства имен. Оба варианта использования приведут к абсолютно одинаковым вызовам API OS (вы можете проверить это в Linux, запустив strace your_program
).
Я считаю очень маловероятным, чтобы кто-то назвал такую функцию, как printf()
это одна из наиболее часто используемых функций. Кроме того, в C++, iostream
предпочтительнее звонков cstdio
функции, такие как printf.
Используя только printf
без std::
может генерировать некоторые конфликты имен и считается плохой практикой для многих разработчиков C++. Google ваш друг на этом, но вот несколько ссылок, надеюсь, это поможет
Почему "использование пространства имен std" считается плохой практикой? http://www.cplusplus.com/forum/beginner/61121/
В студии
Это версия C++ заголовка стандартной библиотеки C @c stdio.h, и его содержимое (в основном) совпадает с заголовком, но все содержится в пространстве имен @c std (за исключением имен, которые определены как макросы в С).
Так что это не должно иметь никакого значения.
Прежде всего, это широко известная функция в библиотеке C, и почти никто не хотел бы называть ее как .
Во-вторых, в заголовочном файле<cstdio>
, оба вstd
пространство имен и глобальное пространство имен. Так что написание префикса или нет работает одинаково.
На мой взгляд, если ваш код и используемая вами библиотека не содержат никаких других пространств имен. Просто используйте, по крайней мере, вы сэкономите свое время на наборе текста.std::
. Или лучше использовать, чтобы избежать возможных конфликтов имен.std::printf
безопаснее.printf
это удобнее.