On Saturday, 14 February 2015 at 17:00:33 UTC, Andrei
Alexandrescu wrote:
There's been recurring discussion about failing constraints not
generating nice error messages.
void fun(T)(T x) if (complicated_condition) { ... }
struct Type(T)(T x) if (complicated_condition) { ... }
If complicated_condition is not met, the symbol simply
disappears and the compiler error message just lists is as a
possible, but not viable, candidate.
I think one simple step toward improving things is pushing the
condition in a static_assert inside type definitions:
void fun(T)(T x) if (complicated_condition) { ... } // no change
struct Type(T)(T x)
{
static assert(complicated_condition, "Informative message.");
...
}
This should improve error messages for types (only). The
rationale is that it's okay for types to refuse compilation
because types, unlike functions, don't overload. The major
reason for template constraints in functions is allowing for
good overloading.
Andrei
I agree, but also for function should conditions that do not
effect overloading go into static asserts.
For example if I were to write an algorithm that works with
forward ranges and can be optimized for random access ranges but
needs assignable elements in any case:
void foo(R)(R r) if(isForwardRange!R && !isRandomAccessRange!R)
{
static assert(hasAssignableElements!R, "informative error
msg");
}
void foo(R)(R r) if(isRandomAccessRange!R)
{
static assert(hasAssignableElements!R, "informative error
msg");
}