c++ - 检查两个函数或成员函数指针的签名是否相等

标签 c++ variadic-templates c++17 type-traits function-signature

我编写了一些代码来检查自由函数的签名是否等于成员函数的签名等。它比较提取的返回类型和函数参数:

#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)>, "");
}

它工作得很好,但是可以简化吗?也许在某些情况下这个解决方案不起作用?

最佳答案

简单来说:没有理由分开return_typearg_types :您可以将它们加入到一个 std::tuple 中与 return_type处于第一位置。

#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)>, "");
 }

关于c++ - 检查两个函数或成员函数指针的签名是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51408881/

相关文章:

c++ - 如何在构造函数中构造预定义的随机数生成器和种子序列?

c++ - 丢失 OpenGL 输出

C++ 构造函数、常量、继承和避免重复

c++ - 参数列表中的元组

c++ - 重载可变长度模板函数的递归结束

c++ - 接受给定数量的 double 的可变参数模板方法?

c++ - 获取 C++ 函数参数的类型

c++ - 理解类型特征的架构

c++ - 动态分配的数组只显示最后的结果

c++ - 使用 Teechart 绘制 sigmoid 曲线最简单最快