Ao usar funções C padrão em C++, é necessário o prefixo" std:"? [duplicado]
Quando usar a função C padrão em C++, devemos pré-fixar todas as funções com {[[2]}?
por exemplo (nome do ficheiro: std.C
):
#include <cstdio>
int main() {
std::printf("hello\n");
printf("hello\n");
}
este ficheiro pode ser compilado com:
g++ -Wall -Werror -std=c++11 std.C
sem qualquer erro.
As minhas perguntas são:- devemos sempre colocar
std::
antes de todas as funções normais da biblioteca C quando são usadas em C++? - Qual é a principal diferença entre ficheiros de cabeçalho como
<stdio.h>
e<cstdio>
?
3 answers
A biblioteca C++ inclui as mesmas definições que a linguagem C biblioteca organizada na mesma estrutura de arquivos de cabeçalho, com o as seguintes diferenças:
- cada ficheiro header tem o mesmo nome que a versão da língua C, mas com um prefixo "
c
" e sem extensão. Por exemplo, o equivalente em C++ para o ficheiro de cabeçalho da linguagem C<stdlib.h>
é<cstdlib>
.- todos os elementos da biblioteca estão definidos no espaço de nomes
std
.No entanto, para compatibilidade com C, os nomes tradicionais de cabeçalho
name.h
(comostdlib.h
) também têm as mesmas definições dentro do espaço de nomes global, Embora o seu uso esteja desactualizado em C++.
(origem)
A parte std::
da chamada std::printf()
é a forma padrão de usar nomes na biblioteca padrão, portanto, sugiro usá-la.
A biblioteca-padrão C++ incorpora a biblioteca-padrão C (com alguns ajustes menores).
Cada cabeçalho C com um nome como <foo.h>
tem um cabeçalho C++ correspondente <cfoo>
. Por exemplo, o cabeçalho C++ <cstdio>
corresponde ao cabeçalho C <stdio.h>
.
Citando a norma ISO C++ de 2011, 17.6.1.2 [cabeçalhos] parágrafo 4:
Na biblioteca-padrão C++, no entanto, as declarações (excepto Nomes que são definidos como macros em C) estão dentro do espaço de nomes ambito (3.3.6) do espaço de nomes
std
. Não é especificado se estes nomes são primeiro declarados no âmbito global do espaço de nomes e são então injectado no espaço de nomesstd
por expresso utilizando-declarações (7.3.3).
Assim #include <cstdio>
, o printf
function definitivamente pode ser referido como std::printf
, e , opcionalmente, pode ser visível como printf
no espaço de nomes global. (Esta opção depende da implementação, não da programador.)
Claro que pode referir-se a ele apenas printf
no âmbito de using namespace std
.
printf
é declarado apenas com no espaço de nomes std
. Se você usar #include <cstdio>
e então se referir a printf
no espaço de nomes global, seu código pode compilar hoje e não compilar em uma implementação diferente.
Por outro lado, como obsoleto , a biblioteca padrão C++ também inclui os cabeçalhos padrão C com os seus nomes originais, como <stdio.h>
. Citando a norma, Secção D. 5 [depr .C. header]:
Cada cabeçalho C, cada um dos quais tem o nome do formulário
name.h
, comporta-se como se cada nome colocado no espaço de nomes da biblioteca-padrão por o cabeçalho cname correspondente é colocado dentro do espaço de nomes global ambito. Não é especificado se estes nomes são primeiro declarado ou definido no âmbito do espaço de nomes (3.3.6) do espaço de nomesstd
e são então injectadas no âmbito global do espaço de nomes por forma explícita utilizando-declarações (7.3.3).
Dado #include <stdio.h>
, o nome printf
é definitivamente visível no espaço de nomes global, e opcionalmente (mais uma vez, esta é a opção da implementação, não a sua) visível como std::printf
.
- std é o espaço de nomes e usando :: (após o std) explicitamente usando as funções do espaço de nomes std. Agora, imagine que você cria seu próprio espaço de nomes e algumas das funções que você criou lá têm o mesmo nome que as funções no espaço de nomes std. Isto pode ser um problema, mas usando o std::func1 e YourNameSpace::func1 você está impedindo este problema.
- Olha para aqui. Obrigado @karma_geek