Reflection happens at run time, or requires an even more complex meta-language (.e.g.
meta-c++) in order to handle them at compile time.
Concepts are, for all intents and purposes, just a simple way of specifying type constraints.
Standard C++ allows you to have very specific type matches (unsigned long, Foo*, etc.) or very
generic types (typename anything), while Concepts add the ability to describe a type that
follows some particular contract (anything that can be added together, anything with a
set(string,int) method, anything with a default constructor, etc.).
However, the unwieldly error messages produced by C++ really aren't directly related to the
lack of Concepts in the current language. It's mostly just the compilers explicitly choosing
to be too verbose.
Say your code looks like this:
typedef vector<int> vint;
vint numbers;
numbers.add("foo");
You're going to get a huge error including things like std::basic_vector<int>::blah::blargh
etc. etc. What is happening is that the compiler is substituting in the actual type in the
AST/IR instead of the type specified by the user.
A compiler like Clang (eventually) will not have this issue. Instead of spitting out the base
template type and every child in the chain of derived templates, it can just say "vint
(typedef std::vector<int>) has no method matching ::add(char*)" and then maybe spit out the
other overloaded versions of ::add() a la GCC.
GCC and the other C++ compilers spit out huge error messages for templates because the
compiler authors just didn't care enough (or didn't think enough) to support cleaner error
messages. Nothing in C++ itself makes those cleaner messages impossible, or even all that
difficult.