C++ std namespace

So everything in the standard C++ library is in the std namespace right? Like std::cout, std::cin, etc. Also the C libraries like stdio.h are in C++ like cstdio.

But it doesn't seem like all the standard libraries are in std.

When I #include <cstdio> I can still just use printf(). When I use <cstdlib> I can do system(). But it also works with std::printf() and std::system(). getline() and std::getline() both work too.

So I guess I'm confused since all of the C++ standard libraries are supposed to be in the std namespace like vectors (std::vector<>).

Could someone tell me why is this?
Last edited on
closed account (48T7M4Gy)
https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library

PS This is not the full story because the following snippet compiles and runs:
1
2
3
4
5
6
7
8
9
10
11
12
13
/* ctime example */
#include <iostream>      /* printf  ???? */
#include <ctime>       /* time_t, time, ctime */

int main ()
{
  time_t rawtime;

  time (&rawtime);
  std::printf ("The current local time is: %s", ctime (&rawtime)); // std:: not needed

  return 0;
}
Last edited on
C++14 ยง17.6.1.2/4
Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).
Last edited on
std::getline is not a C function. The reason you can call it without using std has to do with something called argument-dependent name lookup.

http://en.cppreference.com/w/cpp/language/adl
@Peter87

So when you do getline(std::cin, str) it works because cin is in std?
Is it good practice to explicitly type std in front of everything that is in std?
Is it good practice to explicitly type std in front of everything that is in std?

I don't work in the industry so I couldn't say, but it seems to me the answer is both yes and no -- it depends on the circumstance. The rule of thumb I use is that if I unequivocally want an identifier from a namespace (which I usually do,) I use the namespace qualifier, otherwise I do not.

You might want to check out the answer here which explains why you might not want to use a qualified name for std::swap:
http://stackoverflow.com/a/4782809

But with regard to the OP and C library functions, use the namespace qualifier here. There is no guarantee those identifiers will exist in the global namespace, but they are guaranteed to be in the std namespace.
closed account (48T7M4Gy)
This snippet highlights the points made by p87

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string> // getline()

int main ()
{
    std::string line;
    getline(std::cin, line);
    printf ("%s\n", &line);
    
    return 0;
}


cin is in std:: while getline is in <string> so the connection is indirectly there for the reasons given by peter87.

The printf line warning also compounds the difficulties by warning against not using a c-style string with this function. See also http://stackoverflow.com/questions/10865957/c-printf-with-stdstring

The bottom line is save a whole lot of stuffing around and use the type safety and consistency of the standard C++ library and only venture back into C when you must, say for legacy code changes.
Last edited on
So unless you want to use argument dependent name lookup for the best function or anything else you should explicitly specify the std namespace right?

If so, then should you use std::getline() instead of getline()? Or are there more than one of them with different arguments?

And this still compiles:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string> // getline()
#include <fstream> // std::fstream

int main()
{
        std::fstream file("test.txt"); // let's say "test.txt" exists in current directory
        
        std::string str; // string "str"

        getline(file, str); // in the arguments there nothing in std; just "file" & "str"
                            // why does it compile?
        file.close();

        return 0;
}

and this:

1
2
3
4
5
6
7
8
#include <iostream>

int main()
{
        std::string str; // still compiles without string library included?

        return 0;
}


Note: Using GNU g++ compiler with -std=c++14.
Last edited on
closed account (48T7M4Gy)
The behaviour is consistent with the ideas presented and the additional prospect of undefined behaviour. Put it down to luck if it compiles, I know it does, and avoid it in future knowng the potential for a programming disaster at some later date.

When it all boils down why bother with it and just rely on the far superior and better designed standard library?
Thanks! I will keep in mind to use the standard library.
boost lexical cast wrote:
1
2
getline(file, str); // in the arguments there nothing in std; just "file" & "str"
                    // why does it compile? 

It doesn't matter where the variables are defined. The only thing that matters is the type. file is of type std::fstream and str is of type std::string.

boost lexical cast wrote:
std::string str; // still compiles without string library included?

The GCC implementation of iostream includes <string> but this is nothing you should rely on. It might change in future versions, or if you use another compiler.
Topic archived. No new replies allowed.