In the code below I create an insert_iterator without including the iterator header.
How is possible that this compiles? I'm new to c/c++ so this will likely have an obious explanation.
#include <list>
//#include <iterator>
int main()
{
std::list<int> mylist(10,1);
std::insert_iterator<std::list<int> > it(mylist,mylist.begin());
return(0);
}
It happens to compile because some of the other headers, <list> in your case, is pulling <iterator> as well. This may work fine with one implementation but fail on a different one, or even on the next version of your current library implementation.
You should always include the headers that define the stuff you use, to make sure it will compile everywhere. Note that there are some guarantees of standard headers that are pulled by other standard headers, but I don't think this is one of those exceptions.
Related
#include <iostream>
using namespace std;
int main(){
swap(a[i],a[j])
}
In this the swap function work automatically or I need to create a another swap function to solve this?
swap is not a keyword in C++ but rather a function from the C++ standard library. So to use it you need to bring in the function from the appropriate C++ standard library header. Unfortunately std::swap has been rather itinerant since it first made it into the C++ standard:
Up to but not including C++11, you need to #include <algorithm>
From C++11 you need to #include <utility>
From C++17 you can #include <string_view> instead
Relying on the implicit inclusion of the header means you're not writing portable C++.
This question is pretty weird.
Say I have a file, called idiot.cpp, and it begins with:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>
#include "idiot.h"
and I have a header file, idiot.h. First of all, in idiot.h, do I also have to insert
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>
or do I not?
Second, if I have another source file, say, "bonito.cpp," that uses idiot.h, should I just #include "idiot.h", or should I paste in the code snippet again?
If not, is there any way to shorten this so I don't end up including around 20 headers per file? (hypothetically)
Sorry if this is a pretty dumb question, but I don't use many headers too often.
idiot.cpp does not need to include anything included indirectly by idiot.h to be able to compile.
The more interesting case: bonito.cpp #includes idiot.h and idiot.h includes x.h. If idiot.h only uses the content of x.h for private or anonymous namespace code - and bonito.cpp wants to use something from x.h too, then bonito.cpp should include x.h directly (redundantly).
The justification is simple: idiot.h can't remove something from the public/protected interface without risking breaking client code, so if that happens then the clients have to expect to deal with it - possibly including an extra header too. BUT, the maintainer of idiot.h and idiot.cpp should be free to change private or anonymous namespace content within idiot.h without risking breaking client code, including which headers are included to support that private code.
So, the inclusion is redundant at the time it's done, but that's done in the expectation that it might stop being redundant as idiot.h evolves.
This best-practice model is not automatically enforced - you have to understand the way this should work and actively code to that model.
Example
If idiot.h contains...
#include <string>
#include <vector>
...
class X {
void add(const std::string&);
private:
std::vector<std::string> v_;
};
...then bonito.cpp can reasonably use std::string without including <string>, but should include <vector> itself if it needs std::vector<>.
Consider the following code:
#include <iostream>
using namespace std;
int main () {
srand(time(0));
double dd [10];
for(int i=0;i!=10; ++i) dd[i]= rand()%5+0;
for(auto i:dd)
cout<<i<<' ';
cout<<endl;
exit(100);
}
Why is it compiling without the #include<ctime> and #include<cstdlib> for the calls to time(0) and exit(100)(which is absolutely useless there, I know)? Are they already included in iostream?
The C++ standard, section 17.6.5.2 [res.on.headers], says:
A C++ header may include other C++ headers.
Which means an implementation is free to include other headers when you include one of them. From an implementor's point of view, that's just quite practical, of course.
There are even headers which are guaranteed to include others. For example, <string> implies <initializer_list>.
As for <iostream>, it implies <ios> (which itself implies <iosfwd>), <streambuf>, <istream> and <ostream>. So there is no guarantee for <ctime> and <cstdlib>, and you should include them explicitly for better portability.
To find out which headers are guaranteed to include others, you can either have a look yourself in the standard or in a draft (see all the synopses starting in section 18), or just go to cppreference.com, for example http://en.cppreference.com/w/cpp/header/iostream for <iostream>. It's quite a reliable online C++ reference.
Or you just explicitly include every header you need. Which may be the best choice in the end.
Yes, iostream includes cstdlib (at least in your case; you should not rely on that dependency chain).
Your compiler might have an option to list the dependencies, e.g. for the GNU C compiler, you can use the -M flag to list all includes.
This question already has answers here:
Should I include every header?
(2 answers)
Closed 7 years ago.
consider this translation unit:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::size_t> mp;
mp.insert(std::make_pair("hello", 42));
}
There are two things in this translation unit that are bothering me, and they are
std::size_t
std::make_pair
I have just assumed that <cstddef> and <utility> must have been #included by <string> and <map>.
How rightful is this assumption? At least for make_pair I think there's a pretty strong guarantee because map member interfaces use std::pair. For std::size_t there is no formal guarantee but still it is very very very likely that it is available as soon as you include map or string. The stylistic question number one is Would you explicitly include <cstddef> and <utility> in this translation unit?
This part partly deals with the uncertaintly of some header being already included. However, there's the second part of the question. Suppose we have this
//f.h
#ifndef BIG_F_GUARD
#define BIG_F_GUARD
#include <string>
std::string f();
#endif
//f.cpp
#include "f.h"
std::string f()
{
std::string s;
return s;
}
Second question is: Would you explicitly #include <string> into f.cpp?
I think I made my question clear. Btw. both questions are followed by a big WHY :) Thanks.
In the first case, I probably wouldn't but I should, if I want my code to be properly portable. There's no requirement that map::size_type is size_t, so there's no necessity for <map> to include a definition of size_t. For that matter, size_t can be a type alias rather than a distinct type, so even if size_type is size_t, it needn't have been defined in <map> using that name. So as you say, it's likely but not guaranteed that <map> includes <cstddef>.
In the second case, I definitely wouldn't, because I know I don't need to. IMO a .cpp file is entitled to rely on the headers included by its corresponding .h file, since you kind of expect that if you modify the .h file you potentially need to modify the .cpp file too -- change an interface implies change its implementation, most of the time. And even if you feel I'm not entitled, I can always document that f.h includes <string>, in which case I can rely on that.
Regarding <utility>, I don't know whether <map> is allowed to define std::pair (because it needs it) without defining std::make_pair (which is from the same standard header, and for the sake of argument let's say it isn't needed to define <map>). This would be possible if the implementation's version of <utility> itself includes a bunch of other files, for different bits, and <map> just includes the bit it needs. Specific permission is given for headers to include other headers, but I don't know whether specific permission is given for headers to put things in namespace std without including the whole of the corresponding header. The thing is, in practice it is very difficult to notice that you've forgotten a standard include in these cases, because implementations don't check for you, and that's why I know that in practice I'd quite likely not do it. Luckily it should be any easy fix for anyone porting to an implementation with different header dependencies.
What I tend to do, and it's not necessarily the right thing to do, is to include all the files I need to get the module to compile. The only problem with this is that when dependencies change, you can end up with code included which isn't necessarily used. However a good compiler will normally deal with this.
There's no need to include <string> in your .cpp file however, because it's included through the header file. The contents of any included header files essentially get 'pasted' into your cpp file.
Hope this helps!
No (as long as it's something you know it has to be in there on all platforms targeted; e.g. size_t due to it being one of the parameter/return types of string stuff)
No (as the header file is your under your control and you know it's already included)
To answer your questions:
No
No
Include minimal stuff to make it compile, but no obsolete/additional dependencies that are already fulfilled
Atleast <map> is forced to include <utility> because the template for map looks like this:
namespace std {
template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T> > >
class map;
}
(Standard 23.3/1)
My two bits:
main.cpp: I would #include <cstddef> but probably not <utility> here. You are using std::size_t independent of whether it happens to be defined in the standard library headers. On the other hand, read the documentation on std::map and it is very clear that <map> must somehow define std::pair. There's no reason to #include <utility>. (This is particularly so since the connection between std::pair and is a bit of a WTF without reading the fine documentation.)
f.hh: I would grudingly #include <string> here. Normally it is better to forward declare a class rather than #include the header that defines the class if the class is only used as a reference, a pointer, or a return type. The only reason to #include <string> in f.hh is because forward declaring std::string is a bit tough.
f.cpp: I would #include <string> here. If the return type from f() was some class Foo rather than std::string, the expectation should be that the header merely forward declares Foo. The source file needs to #include the header that specifies class Foo. That the return type is std::string doesn't change this basic concept. Who knows? Some pedantically correct programmer might fix the problem in f.hh. (The problem with f.hh being that it #includes <string> when it doesn't really need to do so.)
I'm having a really nasty problem with some code that I've written. I found someone else that had the same problem on stackoverflow and I tried the solutions but none worked for me.
I typedef several common STL types that I'm using and none of the others have any problem except when I try to typedef a map.
I get a "some_file.h:83: error: expected initializer before '<' token" error when including my header in a test program.
Here's the important part of the header(some_file.h):
#ifndef SOME_FILE_H
#define SOME_FILE_H
// some syntax-correct enums+class prototypes
typedef std::string str;
typedef std::vector<Column> col_vec;
typedef col_vec::iterator col_vec_i;
typedef std::vector<Row> row_vec;
typedef row_vec::iterator row_vec_i;
typedef std::vector<str> str_vec;
typedef str_vec::iterator str_vec_i;
typedef std::vector<Object> obj_vec;
typedef obj_vec::iterator obj_vec_i;
typedef std::map<Column, Object> col_obj_map; // error occurs on this line
typedef std::pair<Column, Object> col_obj_pair;
The includes in some_file.cpp are:
#include <utility>
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <stdio.h>
#include <cc++/file.h>
#include "some_file.h"
The test file simply includes string, vector, and my file in that order. It has a main method that just does a hello world sort of thing.
The funny thing is that I quickly threw together a templated class to see where the problem was (replacing the "std::map<Column..." with "hello<Column...") and it worked without a problem.
I've already created the operator overload required by the map if you're using a class without a '<' operator.
You are getting this problem because the compiler doesn't know what a map is. It doesn't know because the map header hasn't been included yet. Your header uses the STL templates: string, vector, map, & pair. However, it doesn't define them, or have any reference to where they are defined. The reason your test file barfs on map and not on string or vector is that you include the string and vector headers before some_file.h so string and vector are defined, but map is not. If you include map's header, it will work, but then it may complain about pair (unless your particular STL implementation includes pair in map's header).
Generally, the best policy is to include the proper standard header for every type you use in your own header. So some_file.h should have, at least, these headers:
#include <string>
#include <map>
#include <utility> // header for pair
#include <vector>
The downside to this approach is that the preprocessor has to load each file every time and go through the #ifdef ... #endif conditional inclusion processing, so if you have thousands of files, and dozens of includes in each file, this could increase your compilation time significantly. However, on most projects, the added aggravation of having to manage the header inclusion manually is not worth the miniscule gain in compilation time.
That is why Scott Meyers' Effective STL book has "Always #include the proper headers" as item #48.
Is there a #include <map> somewhere in your header file?
Put that in there to at least see if it works. You should be doing that anyway.
You should shift some of those includes into your header file. These need to be placed before your typedef statements.
i.e.
#include <map>
#include <string>
#include <map>
Otherwise, anything else including some_file.h (such as your main program) won't know what they are unless it also places these includes before the #include "some_file.h" include directive in your main program source file. If you do this, the problem should go away.
As several people have pointed out, the compiler isn't finding the definition for map. Since you appear to be including the map header, there's 2 other possible causes i can think of:
Another header file called map is being loaded instead of the std map header. I think this is unlikely.
Another header is #define'ing map to be something else.
One way to check for either is get your compiler to generate the post-processed file, i.e. the source file after it has been run through the C pre-processor but before it has been compiled. You should then be able to find your offending line and see if the map type has been replaced with something else. You should also be able to search back up the file and see what header the #include opulled in.
How you generate the post-processed file is compiler dependent - check the cmd-line flags in the docs for your compiler.