Skip to content

Instantly share code, notes, and snippets.

@vittorioromeo
Created December 12, 2016 08:54
Show Gist options
  • Save vittorioromeo/568f3bdaccced88294b4cb7725f785ff to your computer and use it in GitHub Desktop.
Save vittorioromeo/568f3bdaccced88294b4cb7725f785ff to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cassert>
#include <type_traits>
struct nonesuch {
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
void operator=(nonesuch const&) = delete;
};
namespace detail {
template <class Default, class AlwaysVoid,
template<class...> class Op, class... Args>
struct detector {
using value_t = std::false_type;
using type = Default;
};
template <class Default, template<class...> class Op, class... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
// Note that std::void_t is a C++17 feature
using value_t = std::true_type;
using type = Op<Args...>;
};
} // namespace detail
template <template<class...> class Op, class... Args>
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
template <template<class...> class Op, class... Args>
using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;
template <class Default, template<class...> class Op, class... Args>
using detected_or = detail::detector<Default, void, Op, Args...>;
struct Foo { /* ... */ };
template <class T>
using convertible_to_string = decltype(std::string{std::declval<T>()});
static_assert((is_detected<convertible_to_string, Foo>::value), "");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment