Check that signature of two functions or member function pointer equal

三世轮回 提交于 2019-12-24 14:03:12

问题


I write some code for check that signature of free function is equal to signature of member function, etc. It compare extracted return type and function arguments:

#include <tuple>
#include <type_traits>

template<class Signature>
struct signature_trait;

template<class R, class... Args>
struct signature_trait<R(Args...)>
{
    using return_type = R;
    using arg_types = std::tuple<Args...>;
};

template<class R, class... Args>
struct signature_trait<R(*)(Args...)>
{
    using return_type = R;
    using arg_types = std::tuple<Args...>;
};

template<class R, class U, class... Args>
struct signature_trait<R(U::*)(Args...)>
{
    using return_type = R;
    using arg_types = std::tuple<Args...>;
};

template<class Signature>
using signature_trait_r = typename signature_trait<Signature>::return_type;

template<class Signature>
using signature_trait_a = typename signature_trait<Signature>::arg_types;

template<class Signature1, class Signature2>
using is_same_signature = 
    std::conjunction<
        std::is_same<signature_trait_r<Signature1>, signature_trait_r<Signature2>>, 
        std::is_same<signature_trait_a<Signature1>, signature_trait_a<Signature2>>
    >;

template<class Signature1, class Signature2>
inline constexpr bool is_same_signature_v = 
    is_same_signature<Signature1, Signature2>::value;

struct Foo
{
    void bar(int, int){}
};

void bar(int, int){}

int main()
{
    static_assert(is_same_signature_v<decltype(&bar), decltype(&Foo::bar)>, "");
    static_assert(is_same_signature_v<decltype(&bar), void(int, int)>, "");
    static_assert(is_same_signature_v<decltype(&Foo::bar), void(int, int)>, "");
    static_assert(is_same_signature_v<decltype(&Foo::bar), void(Foo::*)(int, int)>, "");
}

It works fine, but is it possible to simplify? And maybe there some cases where this solution won't work?


回答1:


To simplifty: there is no reason to separate return_type and arg_types: you can join they in a single std::tuple with return_type in first position.

#include <tuple>
#include <type_traits>

template<class Signature>
struct signature_trait;

template<class R, class... Args>
struct signature_trait<R(Args...)>
 { using type = std::tuple<R, Args...>; };

template<class R, class... Args>
struct signature_trait<R(*)(Args...)>
 { using type = std::tuple<R, Args...>; };

template<class R, class U, class... Args>
struct signature_trait<R(U::*)(Args...)>
 { using type = std::tuple<R, Args...>; };

template<class Signature>
using signature_trait_t = typename signature_trait<Signature>::type;

template<class Signature1, class Signature2>
using is_same_signature = std::is_same<signature_trait_t<Signature1>,
                                       signature_trait_t<Signature2>>;

template<class Signature1, class Signature2>
inline constexpr bool is_same_signature_v = 
    is_same_signature<Signature1, Signature2>::value;

struct Foo
 { void bar (int, int) {} };

void bar (int, int) {}

int main ()
 {
    static_assert(is_same_signature_v<decltype(&bar), decltype(&Foo::bar)>, "");
    static_assert(is_same_signature_v<decltype(&bar), void(int, int)>, "");
    static_assert(is_same_signature_v<decltype(&Foo::bar), void(int, int)>, "");
    static_assert(is_same_signature_v<decltype(&Foo::bar), void(Foo::*)(int, int)>, "");
 }


来源:https://stackoverflow.com/questions/51408881/check-that-signature-of-two-functions-or-member-function-pointer-equal

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