Before that I want to tell that I have tried to implement is_assignable on my own. There is no need to show me another examples - I have already seen some implementation.
I would like to fix my solution thanks to you (if it's possible, of course) that'll work out.
So, here is my code:
#include <iostream>
#include <type_traits>
#include <utility>
template<typename LambdaT>
struct is_valid_construction {
is_valid_construction(LambdaT) {}
typedef typename LambdaT lambda_prototype;
template<typename ValueTypeT, typename ExprTypeT = decltype(std::declval<lambda_prototype>()(std::declval<ValueTypeT>()))>
struct evaluate {
evaluate(ValueTypeT val) {
std::cout << "Right!";
}
typedef typename std::true_type value;
};
template<typename ValueTypeT> //The compiler ignores this definition
struct evaluate<ValueTypeT, decltype(std::declval<lambda_prototype>()(std::declval<int>()))> {
evaluate(ValueTypeT val) {
std::cout << "Nope";
}
typedef typename std::false_type value;
};
template<typename ValueTypeT>
void print_value(ValueTypeT val) {
evaluate evaluation(val);
}
};
struct ForTest {};
int main() {
is_valid_construction is_assignable([](auto x) -> decltype(x = x) { });
is_valid_construction is_less_comparable([](auto x) -> decltype(x < x) {});
is_valid_construction is_more_comparable([](auto x) -> decltype(x > x) {});
is_assignable.print_value(int{});
is_less_comparable.print_value(char{});
is_more_comparable.print_value(ForTest{});
return 0;
}
As you can see I am trying to define template structure within template structure. So, I excepted that if the invocation (with declval) of this lambda-expression with parameter of this type (rougly, in terms of substitution) is failed, then SFINAE goes further and should see that the second template definition could be convenient for instantiation. I am asking how could I fix my template structure and its default parameter to push SFINAE use the second definition?