There are times when I want to overload or specialize templates that are already called earlier due to cyclic dependencies.
As they're templates, the solution is usually to split the declaration and the definition.
However, if these templates are meant to be part of a #included library, this means you need two #includes:
- One for declaration, which must be before all specializations.
- One for "late" definition, which must be after all specializations.
(The removed C++ export keyword (pre C++11) was a potential solution, but it had a ton of problems).
Does anyone have any solutions for avoiding the need for the 2nd #include?
I've considered:
Attempting to craft some sort of single "late_call" forwarding template function, which is defined at the end of the source and uses some mechanism to deduce the target function from its parameters. Unfortunately, I can only see how this can work in very special cases.
- [--] Mostly doesn't work.
- [-] Requires a #include at the end of source.
Creating an extendable list of headers to include, via the preprocessor, then including them all at the end via a single final #include. It's possible to hack a list like this with a fixed number of places using a lot of #defines.
- [-] Artificial limit.
- [-] Uses macro #includes, which screw up some tools.
- [-] Ugly as hell.
- [-] Requires a #include at the end of source.
Creating my own manual pragma-type command, then writing an external tool to run over the preprocessed code and move stuff about before compiling.
- [+] Works perfectly.
- [+] Nothing needs to be added to the end of the source.
- [--] This pretty much ensures nobody will ever want to use my library, and I'll probably hate it myself too.
Creating a "late.hpp", in which I add #includes for every late definition, guarded by #ifdefs to check whether they're needed.
- [-] Requires a #include at the end of source.
- [--] Completely breaks modularity.
Manually add the list of late define headers at the end.
- [--] Breaks modularity. Source files may indirectly acquire new late define requirements if other implementations change.
- [-] Ugly.
- [--] Potential source of bugs.