Skip to content

Instantly share code, notes, and snippets.

@remyroez
Created November 1, 2016 08:19
Show Gist options
  • Save remyroez/4581b8924c9a5a0ef5c6d0e055693ea5 to your computer and use it in GitHub Desktop.
Save remyroez/4581b8924c9a5a0ef5c6d0e055693ea5 to your computer and use it in GitHub Desktop.
SFINAE 特定のメンバ変数を持っているかどうかの trait
#include <iostream>
#include <type_traits>
struct has_value_impl {
template <class T, class U = decltype(T::value)>
constexpr static std::is_same<U, int> test_variable(int);
template <typename...>
constexpr static std::false_type test_variable(...);
template <class T, class U = decltype(std::declval<T&>().value())>
constexpr static std::is_same<U, int> test_func(int);
template <typename...>
constexpr static std::false_type test_func(...);
};
template <class T>
constexpr bool has_variable_value = decltype(has_value_impl::test_variable<T>(0))::value;
template <class T>
constexpr bool has_func_value = decltype(has_value_impl::test_func<T>(0))::value;
template <class T>
constexpr bool has_value = has_variable_value<T> || has_func_value<T>;
struct value_trait {
template <typename T, std::enable_if_t<has_variable_value<T>, std::nullptr_t> = nullptr>
static int get(const T &t) { return t.value; }
template <typename T, std::enable_if_t<has_func_value<T>, std::nullptr_t> = nullptr>
static int get(const T &t) { return t.value(); }
};
struct foo {
int value;
};
struct bar {
int value() const { return 456; }
};
struct baz {
float value;
};
template <typename T, std::enable_if_t<has_value<std::decay_t<T>>, std::nullptr_t> = nullptr>
void print_value(const T &t) {
std::cout
<< " has value: "
<< value_trait::get(t)
<< std::endl;
}
template <typename T, std::enable_if_t<!has_value<std::decay_t<T>>, std::nullptr_t> = nullptr>
void print_value(const T &t) {
(void)t;
std::cout
<< " doesn't have value"
<< std::endl;
}
int main()
{
foo a{123};
bar b;
baz c{789.0f};
int d = 1000;
std::cout << "a";
print_value(a);
std::cout << "b";
print_value(b);
std::cout << "c";
print_value(c);
std::cout << "d";
print_value(d);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment