I thought of this a few weeks after I my last edit in that thread. I think the way to phrase it would be to #include things in foreign libraries that you cannot have a dependece on your code.
For example, if you write a class MyClass, you know that std::string can't possibly have MyClass as a dependency, and therefore it's ok to #include. |
If its in a foreign library, how could it possible depend on your code in terms of compile-dependency? I mean.. it is already compiled! ;-)
Anyway, the rules I've seen about when to include/forward declare stuff from foreign libraries vary as much as the definition of "foreign library".
But I got the point. Maybe std::string is not a good example as there are good reasons to even include string already in your precompiled header. ;)
Let me make another example of an "type that contains implementation defined behaviour":
1 2 3 4 5
|
#ifdef NDEBUG
typedef _fast_file_allocator FileAllocator;
#else
typedef _debug_file_allocator FileAllocator;
#endif
| |
I hope you agree with me that it's not a good idea to try to forward-declare FileAllocator every time "by hand"? That's also because the actual
type of FileAllocator depends on some other attributes (as whether NDEBUG is defined or not). My recommendation is, to provide a forward-declaring header file for all people who need correct forward declarations of FileAllocator.
1 2 3 4 5 6 7 8
|
// FileAllocatorFwd.h
#ifdef NDEBUG
class _fast_file_allocator;
typedef _fast_file_allocator FileAllocator;
#else
class _debug_file_allocator;
typedef _debug_file_allocator FileAllocator;
#endif
| |
If there is no such forward-declaring header, it's probably better to include the original header than to copy'n'paste the #ifdef with those ugly class names around into every header file who only uses file allocator pointer.
Hm... while writing this, I recognized that actually I am only suggesting, that "forward declarations" sometimes mean "include an
other header file than the one with the complete declaration that has a forward declaration inside".
ACK as in you don't approve? XD |
Huh? Actually ACK as in "I approve this" :-D
You are writing about the fact, that a header should always include enough so that anyone including it is never
forced to include something else before to make it compile. That's what I think too. Many people suggest that they should include that absolute minimum (which means: Nothing), even if this means users are forced to include files before this header to make it compile. This is wrong thought, as it doesn't remove dependencies but only shift them around and lead to include-order-hell and hidden circular references.
Ciao, Imi.