Why is there no stlfwd header and can the non-existence of it be considered a defect?
What would be the purpose of forward declaring say less
or sort
or really any other algorithm? If you're passing a general purpose algorithm around it will almost certainly be as a template type and not need a forward declaration at all.
That leaves us with the container types. There are definitely cases where forward declarations of them would be useful but I suspect that it was simply decided that as each container definition is relatively simple (compared to iostreams) it would be preferable to just use the full include rather than a <containerfwd> include for example.
Forward headers for STL containers
No, unfortunately not. The standard only introduced <iosfwd>
for backward compatibility to support code that was written for the old, non-templated IO streams library.
Include iosfwd appears to cause a namespace issue?
You have two problems here. The first problem is that you are using std::endl
, but that is defined in <ostream>
, which is not included.
The second problem is that you are only including the header <iosfwd>
, which forward declares many of the iostream types. Forward declaration lets the compiler know that the types exist. However, you are trying to use these types' functionality. Since you are doing that, you should include <ostream>
, rather than <iosfwd>
. <ostream>
contains std::endl
, so that should take care of everything.
Does the standard specify what headers include other headers?
As far as I know, the standard does not specify what headers include other headers - that's implementation defined and not something you should ever rely on. Include what you use.
Also, you may want to prefer http://cppreference.com/ over http://cplusplus.com/ as it is (IMHO) of much higher quality.
Why is the header file compiled successfully without include statement?
On some platforms some system headers will include files that other platforms don't. On any version of MSVC I've used <vector>
includes <string>
. On GCC - to my experience - it doesn't so this code would not compile. Generally you want to make sure to include every thing you use, even if it compiles without.
To see if this is the case with your compiler you can save preprocesser output to a file (for example, this is how you do it in GCC and MSVC). Then you can search for basic_string and see where it was included from. In my case with MSVC:
#line 7 "w:\\program files (x86)\\microsoft visual studio 12.0\\vc\\include\\vector"
#line 1 "w:\\program files (x86)\\microsoft visual studio 12.0\\vc\\include\\stdexcept"
#line 1 "w:\\program files (x86)\\microsoft visual studio 12.0\\vc\\include\\xstring"
You can see that vector
includes stdexcept
which includes xstring
which is the where the implementation of std::basic_string
is defined for MSVC
Note that you could also just look at the standard headers , but it might be hidden somewhere that isn't obvious (I didn't expect it to be through <stdexcept>
).
The moral of the story is that even if it compiles, be sure you are always including what you use in order to avoid running into issues from this later down the road (this goes for including files in general, not just the standart library).
Response to Update
As others have said, all #include
does is essentialy paste the code from the header file where the include directive is. So after preprocessing (when includes are "pasted"), what the compiler will see is:
// contents of <vector> header would be pasted here
class StrBlob {
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob();
StrBlob(std::initializer_list<std::string> i1);
bool empty() const {return data->empty();}
void push_back(const std::string &s) {data->push_back(s);}
void pop_back();
std::string &front();
std::string &back();
private:
std::shared_ptr<std::vector<std::string>> data;
void check(size_type i, const std::string &msg) const;
};
int main() {
int i = 0;
return 0;
}
The primary difference between before and now is that now you are linking as well as compiling. At this point though I'm honestly not sure exactly what it is causing this, but that isn't something that's worth knowing in my opinion since it is just an implementation detail of your compiler's standard library.
The main thing to know is to always include what you use (you're also missing <memory>
for std::shared_ptr
). What system headers may or may not include is implementation dependent and thus not something you should ever rely on or (hopefully) need to worry about.
When should I `#include ios`, `#include iomanip`, etc.?
If I follow this rule religiously, will I ever run into a case where I need to include
<ios>
,<iosfwd>
,<istream>
,<ostream>
, and/or<streambuf>
in my application code?
Well, <iostream>
includes <ios>
, <streambuf>
, <istream>
, and <ostream>
. And <iosfwd>
are just forward declarations, so you don't really need that one either. So... I suppose, yes.
<fstream>
gives you all the file-related stuff: filebuf
, ifstream
, ofstream
, and fstream
(and their wide counterparts).
<sstream>
similarly gives you all the stringstream
types and stringbuf
.
All that leaves you with is remembering what's in <iomanip>
, which isn't that much, but you could always just look it up.
Related Topics
C++ Templates Angle Brackets Pitfall - What Is the C++11 Fix
How to Use Std::Filesystem on Gcc 8
Can Compiler Generate Std::Move for a Last Use of Lvalue Automatically
Calling a Virtual Function from the Constructor
What Are Some Better Ways to Avoid the Do-While(0); Hack in C++
Fastest Implementation of Sine, Cosine and Square Root in C++ (Doesn't Need to Be Much Accurate)
Writing Function Definition in Header Files in C++
Get Absolute Value Without Using Abs Function Nor If Statement
How to Tell Cmake to Use Clang on Windows
Why Explicitly Delete the Constructor Instead of Making It Private
Why Does Using a Temporary Object in the Range-Based for Initializer Result in a Crash
Std::String in a Multi-Threaded Program
Macro Definition Containing #Include Directive
How to Automatically Avoiding Stepping into Certain Functions in Visual Studio