I agree with David Rodríguez - dribeas and in defense of compiler writers consider this example:
#include <type_traits>
class A {};
// I want the nice error message below in several functions.
// Instead of repeating myself, let's put it in a function.
template <typename U>
void check() {
static_assert(std::is_convertible<U*, const volatile A*>::value,
"U doesn't derive publicly from A "
"(did you forget to include it's header file?)");
}
template <typename U>
void f(U* u) {
// check legality (with a nice error message)
check<U>();
// before trying a failing initialization:
A* p = u;
}
class B; // I forget to include "B.h"
int main() {
B* b = nullptr;
f(b);
}
When the instantiation of f<B>
starts the compiler (or the compiler writter) might think: "Humm... I need to instantiate check<U>
and people always complain that compiling templates is too slow. So I'll keep going and perhaps there's something wrong below and I don't event need to instantiate check
."
I believe the reasoning above makes sense. (Notice that I'm not a compiler writter so I'm just speculating here).
Both GCC 4.8 and VS2010 keep compiling f<B>
, postponing the instantiation of check<B>
for later. Then they find the failing initialization and provide their own error messages. VS2010 stops immediately and I don't get my nice error message! GCC keeps going and yields the message that I wanted (but only after its own).
Metaprogramming is tricky for the programmers and for the compilers. static_assert
helps a lot but it's not a panacea.