Is the std namespace split into many header files?

Before knowing that the declaration of namespace can be split, I had the question that why I can use some entity defined inside the namespace std but not the others unless I explicitly #include the related header file.

Now I have an idea about how the namespace std is defined. I post it just to confirm, or if wrong, look for a correct explanation.

1
2
3
4
5
6
// header file iostream
// can be used by #include <iostream>
namespace std
{
    // objects such as cout, cin are defined
}

1
2
3
4
5
6
7
8
9
10
11
// header file string
// can be used by #include <string>
namespace std
{
    class string
    {
        // string class definition
    }
	
    // other functions related
}


So, in the main program, #include <iostream> will define part of the std namespace, but not including the class string. Although class string is indeed defined inside the same namespace, it is in the separate header file <string>. So I have to #include <string> to use std::string.

Am I correct? Do you have something supplement to this?

One more question, is the C library inherited by C++ in the std namespace?
> So, in the main program, #include <iostream> will define part of the std namespace

Yes.

> but not including the class string.

It may or may not indirectly include <string>. One standard header is allowed to include other standard headers.


> So I have to #include <string> to use std::string

Yes. To use the full functionality of std::string in a portable program, we have to include <string>


> is the C library inherited by C++ in the std namespace?

Yes. For instance, a superset of the functionality provided by the C89 header <math.h> is provided by the standard library header <cmath>
http://en.cppreference.com/w/cpp/header/cmath
Last edited on
I have tried the <cmath> header.
If <cmath> is defined in the std namespace, why is the scope operator not necessary to call cos function? (both std::cos(0) and cos(0) compile)

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

int main()
{
	std::cout << cos(0) << std::endl;
}



And, if <string> is indirectly included, will we have the full functionality without explicitly #include <string>?
Last edited on
> If <cmath> is defined in the std namespace,
> why the scope operator is not necessary to call cos function?

For compatibility with C, the C ++ standard library provides the C headers <math.h> etc.

An implementation is allowed to place the names in the C library in the global namespace first and then inject them into namespace std via using declarations. It is also allowed to declare/define these names within namespace std and then inject them into the global namespace scope.

To write portable C++ code, #include <cmath> and use std::cos()
To use the C library in compatibility mode, #include <math.h> and use ::cos()

> And, if <string> is indirectly included,
> will we have the full functionality without explicitly #include <string>?

Yes. If.

Last edited on
JLBorges, thanks a lot!
Nikko YL wrote:
if <string> is indirectly included, will we have the full functionality without explicitly #include <string>?


There's a common catch for the beginners: a library header may be partially indirectly included by another library header. #include <iostream> always includes the part of <string> where the class std::string is defined, but in most implementations it does not include the parts of <string> where std::getline is defined or where string I/O and comparison operators are defined. So even though you would be able to write std::string s = "abc"; if you included <iostream> without including <string>, you wouldn't be able to write std::cout << s; or if(s1 == s2). Of course none of that matters if you always include what you use.
Last edited on
How can a header file be partially included?
Preprocessor macros.

headerA
1
2
3
4
void bar();
#ifdef FUBAR
int foo();
#endif 

headerB
1
2
#include <headerA>
// bar() is now known 

headerC
1
2
3
4
#define FUBAR 1
#include <headerA>
#undef FUBAR
// both foo() and bar() are now known 

So is it correct to say the following?
<headerC> is the header file users normally #include for full functionality. But the actual definition is in <headerA> which is not known by users.
Yes, actual implementations within the library are usually split across many more headers. <string>, <iostream>, etc are just the interfaces.

case in point, <string> in GCC is http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/include/std/string?view=markup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING	1
	
#pragma GCC system_header
	
#include <bits/c++config.h>
#include <bits/stringfwd.h>
#include <bits/char_traits.h>  // NB: In turn includes stl_algobase.h
#include <bits/allocator.h>
#include <bits/cpp_type_traits.h>
#include <bits/localefwd.h>    // For operators >>, <<, and getline.
#include <bits/ostream_insert.h>
#include <bits/stl_iterator_base_types.h>
#include <bits/stl_iterator_base_funcs.h>
#include <bits/stl_iterator.h>
#include <bits/stl_function.h> // For less
#include <ext/numeric_traits.h> 
#include <bits/stl_algobase.h> 
#include <bits/range_access.h>
#include <bits/basic_string.h>
#include <bits/basic_string.tcc> 
	
#endif /* _GLIBCXX_STRING */ 
I previously thought that each library headers are implemented in its single file.

I now know it is more complicated. Thanks for telling me that.
Topic archived. No new replies allowed.