Most of the hana headers include also forward declaration headers contained in the subfolder fwd
, e.g. #include<boost/hana/fwd/pair.hpp
.
AFAIK forward declaration headers declare things instead of defining them, so the user can have a access limited to pointers (and references) to the functions and objects.
What sense does it make for boost::hana
, which is header-only templated library? The only thing that comes to my mind is that forward declarations are good enough if you do not intend to instantiate the declared templates, but then - what is the point of using them in the first place?
By looking at the library source I sense it is something very smart, which I still do not comprehend.
Imagine I need only very specific instances of the boost::hana
templates. Would it work, if I define and instantiate them in one translation unit, and link to them from all the other units, using forward declarations?
There is a little information on this in the manual here:
This subdirectory contains the forward declaration of everything in the library. It is essentially a mirror of the
boost/hana/
directory, except all the headers contain only forward declarations and documentation. For example, to include thehana::tuple
container, one can use theboost/hana/tuple.hpp
header. However, if one only wants the forward declaration of that container, theboost/hana/fwd/tuple.hpp
header can be used instead. Note that forward declarations for headers inboost/hana/ext/
andboost/hana/functional/
are not provided.
Also from a discussion with the author here:
The rationale is so that we can #include lightweight declarations instead of full blown definitions when only a declaration is requried. This can help with compile times. Also, it’s necessary for some circularly-dependent stuff.
and:
And finally, I think it makes for a nice separation between interface and implementation, and also it gives a place to systematically put documentation. Since the implementation is sometimes hairy, I think it’s nice not to entangle the documentation with it.
There it is straight from the horse's mouth. I've found it is quite necessary to separate implementation for the whole chicken/egg problem with circular dependencies. This is a clean way of doing that, that I've adopted in my own projects.