Jeff Garland wrote:
Scott Meyers wrote:
Some Boost libraries, such as SmartPtr and Variant, offer a single header with declarations for all library functionality as well as a set of headers for subsets of functionality. For example, smart_ptr.hpp declares all of shared_ptr, shared_array, weak_ptr, scoped_ptr, scoped_array, and intrusive_ptr. If I don't want all these declarations, I can use more specific headers, e.g., shared_ptr.hpp or scoped_array.hpp. Such libraries allow me to choose between the convenience of a single comprehensive header or the precision of multiple targeted headers.
Other libraries seem to offer only the collection of targeted headers. For example, FileSystem offers five headers, but there doesn't seem to be a comprehensive filesystem.hpp.
I think you missed the boost/filesystem.hpp -- I believe it includes "everything" except the fstream.hpp.
Similarly, Lambda seems to offer only targeted headers; there doesn't seem to be a single "declare everything in Lambda" header. (There is a lambda.hpp, but it's not comprehensive, e.g., it doesn't declare Lambda's bind.)
Ok.
I find that this kind of inconsistency among libraries degrades my experience as a Boost user, especially when I'm first learning to use a library. More than once I've spent time puzzling over a compilation error, only to discover that my mistake was not including a needed header. (I seem to make this error most commonly when using Lambda.)
Yeah, that's happened to me before too.
Is there some kind of Boost convention or policy on whether a library should offer a comprehensive "declare everything in the library" header in addition to more targeted headers?
There are header and directory policies:
http://www.boost.org/more/header.htm http://www.boost.org/more/lib_guide.htm#Directory_structure
Unfortunately, it doesn't mention these issues. Overall I'd say that the trend is toward granular headers for the usual dependency / design issues with a single all-inclusive header...but, as you point out it's not 100% consistent. There are special cases -- like libraries that provide serialization support normally don't put this in the 'all-inclusive' header because they don't want to drag in all of the serialization stuff unless it's really needed. Or the fstream case in filesystem which avoid the iostream headers unless you want to use the fstream with filesystem::path.
I think it would be good to improve on this. Care to take a crack at writing some guidelines for the docs?
Each library can offer an all-enclusive header file, with a proviso that the particular header is overkill if one only wants to do a subset of what the library offers at any one time. From a user's point of view I think this would be good for all libraries to do. Some programmers do not care, at least initially, that all headers might be included, even if it increases compile time, as long as they can get their code to compile/link. Only after they become accustomed to a particular library do they care about limiting the headers being included for the particular usage at hand.