问题
Given a (reduced) implementation of the detection idiom
namespace type_traits
{
template<typename... Ts>
using void_t = void;
namespace detail
{
template<typename, template<typename...> class, typename...>
struct is_detected : std::false_type {};
template<template<class...> class Operation, typename... Arguments>
struct is_detected<void_t<Operation<Arguments...>>, Operation, Arguments...> : std::true_type {};
}
template<template<class...> class Operation, typename... Arguments>
using is_detected = detail::is_detected<void_t<>, Operation, Arguments...>;
template<template<class...> class Operation, typename... Arguments>
constexpr bool is_detected_v = detail::is_detected<void_t<>, Operation, Arguments...>::value;
}
we can check if a class foo
contains a member function bar
struct foo {
int const& bar(int&&) { return 0; }
};
template<class T, typename... Arguments>
using bar_t = std::conditional_t<
true,
decltype(std::declval<T>().bar(std::declval<Arguments>()...)),
std::integral_constant<
decltype(std::declval<T>().bar(std::declval<Arguments>()...)) (T::*)(Arguments...),
&T::bar
>
>;
int main()
{
static_assert(type_traits::is_detected_v<bar_t, foo, int&&>, "not detected");
return 0;
}
However, as you can see, we need to write "complicated code" for every method we want to detect.
Can we encapsulate the idea of
bar_t
into a more generic test? I would like to provide the operationfoo::bar
and the desired argument type and perform a test likestatic_assert(type_traits::is_detected_v<bar_t, foo, int&&>, "not detected");
.
[I've created a live demo of this example.]
来源:https://stackoverflow.com/questions/35847567/how-can-we-modify-the-detection-toolkit-to-check-if-a-class-has-a-member-functio