I'm not sure what purpose your desire would serve, or even if it makes sense. For example, this is a contradiction: "I wish the compiler could aggressively look for and link to instances that have the same binary representation - even if they have disparate type information."
The generated object code for thing<int> and thing<double> are likely to not be identical, except for where the types are manipulated. Because thing<int> and thing<double> generate entirely different classes, they can actually be radically different. First, C++'s resolution rules allow them to be actually different C++ code. But even if it reuses the C++ code, because that code then goes through the optimization phases, what comes out the other side may not have the kind of trivial relationship you're thinking of.
I don't think this is unique to C++; it should be true of any language that has non-type erased generics that generates native code. I'm thinking of Haskell, OCaml and Rust - but if people who know those languages and compiler chain better think I'm wrong, please speak up.
Personally, I find C++'s templates to be extremely useful and powerful. I also think they are demonstrably not as nearly as hackish as the C preprocessor, as evidenced by the fact that they actually have knowledge of types. The C preprocessor is just textual substitution, while C++'s templates are far, far from that.