Этот вопрос был вдохновлен этим ответом. Интересно, какие/были лучшие способы упростить его в данных стандартах. Один, который я знаю и использовал лично/по-прежнему, поскольку С++ 14 - это макрос REQUIRES(x)
:
С определением:
template<long N>
struct requires_enum
{
enum class type
{
none,
all
};
};
#define REQUIRES(...) requires_enum<__LINE__>::type = \
requires_enum<__LINE__>::type::none, \
bool PrivateBool = true, \
typename std::enable_if<PrivateBool && (__VA_ARGS__), int>::type = 0
И используйте, если даже для не-templated вызовов функций:
template<REQUIRES(sizeof(int)==4)>
int fun() {return 0;}
int main()
{
fun(); //only if sizeof(int)==4
}
Оригинальный REQUIRES
, я использую это post.
Каковы другие хорошие методы?
Некоторые примеры SFINAE, которые требуют некоторого времени или долгое время для понимания для читателя, который только начал приключение с SFINAE:
Pre-С++ 11 Пример SFINAE (Источник):
template <typename T>
struct has_typedef_foobar {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(typename C::foobar*);
template <typename>
static no& test(...);
// If the "sizeof" of the result of calling test<T>(nullptr) is equal to sizeof(yes),
// the first overload worked and T has a nested type named foobar.
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
};