I keep running into annoying problems.
One is having macro conflicts. I like to just have stuff like
#define MIN(a,b) ( (a)
<(b) ? (a) : (b) )
for myself, which is fine and all, until you try to mix multiple codebases that all have their
own idea of what that macro should be.
(obviously MIN is not actually a big deal because everybody agrees on what that should be; a bigger
issue is like if people are doing a #define of malloc or SWAP or Log).
The cleanest thing I've come up with is :
1. All #defines in headers must be "namespaced" , like CB_MIN instead of just MIN.
2. Never #define anything that looks like it's in global namespace (eg. no #defining malloc)
3. Make a header called "use_cb.h" which does
#define MIN CB_MIN
#define malloc cb::malloc
Basically this is hacky way of "namespacing" the macros and then "using the namespace" in the CPP
files. Not awesome.
The other issue I'm running into is generic functions and template specialization.
Say you're working with some codebase, let's call it "stupidlib". They have their own ::swap
<typename Type > inline void stupidSwap(Type &a,Type &b)
Type c = a; a = b; b = c;
And then they also override it for some special cases :
inline void stupidSwap
<stupidObject>(stupidObject &a,stupidObject &b)
Now, you are trying to munge stupidlib into a codebase that just uses the normal STL. It's
putting objects in containers, and you want it to use std::swap correctly, but when you call
std::swap on a stupidObject - it doesn't see that a nice swap override has been made.
So far as I can't tell you cannot fix this. It is impossible to make std::swap redirect to
stupidSwap for the cases where stupidSwap has been overriden. You have to do it manually for
each object type, and any time somebody changes stupidlib your code can silently break.
Now there is a pretty easy solution to this : never define a generic operation which already exists
in the STL - just override the STL.
The problem is that people like to replace bits of the STL all the time. Hell I do it, because the STL
headers are so retardedly bloated they kill compile times, so I try to use them minimally.
But that "solution" isn't really a solution anyway - it's just a convention to use the STL defs as bases
for overloading when they exist. When you're trying to overload a generic operation that isn't defined
in the STL you go back to having the same problem - two codebases can define that operation and various
specializations, and you can't mix them.
Generic/template programming simply does not work well when mixing codebases.