For instance, in C, every function has a unique, global name. That means the implementation in the compiler can be a hash-table from string to implementation. C++ allows function overloading; now, our 'hash table' is a much more complicated thing: first, we must consider every function in the overload set no matter what; second, we must pick which function is "best" — usually through some complicated unification scheme. In all, this means that C function lookup is O(1) (probabilistic), whereas C++ function lookup is O(n) at best, but with unification it might be O(n^2) or O(n^3). I've seen slow compiling code with hundreds of identically named functions.
Templates are slow for two reasons: (1) they get shared via header files, so they get reparsed over-and-over-and-over; and, (2) they're implemented with a stringy interpreter whose job is to instantiate copies of the code. This is distinctly slower than macro expansion; generally, macro instantiation is of code and so occurs in source files — only requiring a single parse; and, also, there's just string-replacement, not an interpreter.
But ... here's the thing. You can make your C++ code compile fast by simply not using slow paths through the compiler.