Skip to content

Instantly share code, notes, and snippets.

@andijcr
Created August 8, 2019 13:51
Show Gist options
  • Save andijcr/07fddd9cfa27e38db460b9914ba445b4 to your computer and use it in GitHub Desktop.
Save andijcr/07fddd9cfa27e38db460b9914ba445b4 to your computer and use it in GitHub Desktop.
c++: detecting if a type is a T or a function returning T (here demostrated with std::pair)
#include <type_traits>
#include <tuple>
template <typename T> struct is_pair : public std::false_type {};
template <typename T1, typename T2>
struct is_pair<std::pair<T1, T2>> : public std::true_type {};
template <typename T> constexpr auto is_pair_v = is_pair<T>::value;
template <typename T, typename = std::void_t<>>
struct is_lazy_pair : public std::false_type{};
template <typename T>
struct is_lazy_pair<T, std::enable_if_t<is_pair_v<std::invoke_result_t<T>>>> : public std::true_type{};
template <typename, typename = std::void_t<>>
struct is_pair_or_fnpair : public std::false_type{};
template <typename T>
struct is_pair_or_fnpair<T, std::enable_if_t<is_pair_v<T>>> : public std::true_type {};
template <typename T>
struct is_pair_or_fnpair<T, std::enable_if_t<is_lazy_pair<T>::value>> : public std::true_type {};
auto mk(){
return std::pair{1, 2};
}
auto mk2=[]{return std::pair{1,2};};
template <typename K, typename V> auto lkv(K &&k, V &&v) {
return [=] { return std::pair{k, v}; };
}
struct A{};
template<typename T>
int fun(T&& t){
static_assert(is_pair_or_fnpair<T>::value);
return 1;
}
auto e = fun(mk()); // ok, is a pair
auto a = fun(mk2()); // ok, is a pair
auto b = fun(lkv(1, 2)); // ok, returns a lambda returning a pair
//auto c = fun(A{}); // triggers static assert
//auto d = fun(int{}); // triggers static assert
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment