Skip to content

Instantly share code, notes, and snippets.

@jpleau
Created December 4, 2015 12:12
Show Gist options
  • Save jpleau/0ec946e95675177de667 to your computer and use it in GitHub Desktop.
Save jpleau/0ec946e95675177de667 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <type_traits>
#include <string>
#include <typeinfo>
using namespace std;
struct Obj {};
struct ObjWithFoo {
using foo = char;
};
template <typename T, typename>
struct helper_foo : false_type {};
template <typename T>
struct helper_foo<T, decltype(((void)declval<typename T::foo>(), 1))> : true_type {};
template <typename T>
struct has_foo {
static const bool value = helper_foo<T, int>::value;
};
template <typename T, typename = T>
struct helper_fallback : true_type{};
template <typename T>
struct helper_fallback<T, enable_if_t<is_integral<T>::value, T>> : false_type{};
template <typename T>
struct helper_fallback<T, enable_if_t<is_floating_point<T>::value, T>> : false_type {};
template <typename T>
struct is_fallback {
static constexpr bool value = helper_fallback<T>::value;
};
template <typename T>
enable_if_t<is_integral<T>::value, void> test(T t) {
cout << "is_integeral<T>::value == true" << endl;
}
template <typename T>
enable_if_t<is_floating_point<T>::value, void> test(T t) {
cout << "is_floating_point<T>::value == true" << endl;
}
template <typename T>
enable_if_t<is_fallback<T>::value && has_foo<T>::value, void> test(T t) {
cout << "fallback -- T::foo exists" << endl;
}
template <typename T>
enable_if_t<is_fallback<T>::value && !has_foo<T>::value, void> test(T t) {
cout << "fallback -- T::foo does not exist" << endl;
}
template <typename T>
void multi_test(T t) {
test(t);
}
template <typename T, typename... Args>
void multi_test(T t, Args... args) {
multi_test(t);
multi_test(args...);
}
int main() {
int i = 10;
double d = 20.3;
Obj o;
ObjWithFoo o2;
multi_test(i, d, o, o2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment