How can we modify the detection toolkit to check if a class has a member function with a specific signature?

隐身守侯 提交于 2019-12-22 06:44:52

问题


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 operation foo::bar and the desired argument type and perform a test like static_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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!