" - " (SFINAE). , , ++ , . . , (.. , ), , , , - .
. -, , "IsAdaptable", , . , operator ! , ? , SFINAE, - , . , "enable if". enable-if:
template <bool Condition, typename T> struct EnableIf {
typedef T type;
};
template <typename T> struct EnableIf<false, T> {
};
. - - , , EnableIf type, , .
enable if , , , . , , , :
template <typename T>
ReturnType MyFunction() {
}
, , T "Predicate". :
template <typename T>
typename EnableIf<Predicate<T>::value, ActualReturnType>::type MyFunction() {
}
, MyFunction T, . -, Predicate<T>::value , EnableIf type, ActualReturnType, . , Predicate<T>::value , EnableIf type, . , " ", . , , . , , MyFunction .
, operator ! :
template <typename Pred>
typename EnableIf<IsAdaptable<Pred>::value, std::unary_negate<Pred> >::type
operator! (const Pred& p) {
return std::not1(p);
}
, : " operator ! , ". - IsAdaptable, .
, IsAdaptable . , , . ! , .
, IsAdaptable, - SFINAE . . , , , , "" , "", , "" "", "" , - . :
- , , . , "" "" "" .
- , , . , , "", , .
? , , :
template <typename T> Yes TestFunction(typename T::argument_type* argument);
template <typename T> No TestFunction(...);
TestFunction. T a T::argument_type*. varargs. , T :
TestFunction<T>(NULL);
, T , argument_type, . . - , ++, varargs (, ...) - , . , Yes, T argument_type, , No . - - , , , , T !
, , . , Yes No, :
typedef char Yes;
struct No {
char dummy[32];
};
, sizeof(Yes) == 1 sizeof(No) > 1. IsAdaptable:
template <typename T> struct IsAdaptable {
private:
typedef char Yes;
struct No {
char dummy[32];
};
template <typename U> static Yes test(typename U::argument_type*);
template <typename U> static No test(...);
public:
static const bool value = (sizeof(test<T>(0)) == sizeof(Yes));
};
, true, test<T>(0) Yes false . , sizeof ( , ), .
:
template <bool cond, typename T> struct EnableIf {
typedef T type;
};
template <typename T> struct EnableIf<false, T> {
};
template <typename T> struct IsAdaptable {
private:
typedef char Yes;
struct No {
char buffer[32];
};
template <typename U> static Yes test(typename U::argument_type*);
template <typename U> static No test(...);
public:
static const bool result = (sizeof(test<T>(0)) == sizeof(Yes));
};
template<typename T>
inline typename EnableIf<IsAdaptable<T>::result, std::unary_negate<T> >::type operator !(const T& pred) {
return std::not1( pred );
}
, !