I\'m using SFINAE in the style of this answer in order to call a generic vector object by using an appropriate member function. For example, the following code calls o
SFINAE comes to us from [temp.deduct]/8, emphasis mine:
If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written using the substituted arguments. [ Note: If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution process. —end note ] Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure.
The immediate context is what's in the template declaration. In your initial example:
template::value> >
auto get(V const& v, int i, rank<2>) const
V
is in the immediate context, so a substitution failure on the enable_if
is just a deduction failure.
However, in your second example:
template::value> >
auto get(int i, rank<2>) const
VectorType
is not in the immediate context of get
, so a failure here would not be a deduction failure, it would be a hard error.
Unless VectorType
happens to have all of these operators.
The solution to any template problem is to just add more template. In this case, force VectorType
to be in the immediate context by introducing another type:
template::value> >
auto get(int i, rank<2>) const
And call get<>()
.