What Is the <Iosfwd> Header

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



Leave a reply



Submit