I just learned that C++ concepts are much more superior than SFINAE because functions constrained by concepts are ordered, meaning a more constrained function is considered a better match than a less constrained one.
How exactly are the rules used by the compiler to estimate how much constrained a function is? How do these rules interact with conventional overload resolution when mixing non-restrained and restrained overloads?
To make simple..., during the overload resolution process:
First, all functions that would be viable without the constraints but whose constraint are not satisfied are considered not viable.
So the set of viable overload contains functions, template functions and constrained templated function with satisfied constraints.
Then the best overload is chosen, during the first step without considering constraints. At each of these steps, the compiler compare 2 candidates if one appears to be better than the other, this candidate is considered to be a better match than the other, without considering any further criterium:
For example:
template <Concept1 T> foo(T&&);
template <Concept2 T> foo(const T&);
template <Concept3 T> foo(const T&);
void g(){
int i=10;
const int& j =i;
foo (j) // the compiler will check the 2 last foo
//to see if one is more constrained than the other
foo (i) //the first foo is selected even if the second or third foo could look like they are more constrained
}
A template T1 is more constrained than a template T2 if the compiler can prove that, for any possible set of template arguments, if the constraint of T1 is satisfied then the constraint of T2 is satisfied. It check if it can prove:
constraints of T1 statisfied ==> constraints of T2 satisfied
where ==>
means imply.
To do such a demonstration, the compiler is quite limited. It will only use a subset of boolean algebra (only and
and or
operations) where the operand are a decomposition of constraints and concept into so-called atomic constraints. To simplify atomic constraints are the operands of none folded "logical and expressions" and "logical or expressions" that appear within constraints and concept definitions.
I suppose that trying to go further would result in copying the standard. So here is a link to the most pertinent standard section [temp.constr]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With