c++ - Check that signature of two functions or member function pointer equal
问题描述
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?
解决方案
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)>, "");
}
推荐阅读
- angular - 加载资源失败:服务器响应状态为 404(未找到)Angular 7
- python-3.x - Python,将超过 200 个用户添加到电报频道的 Telethon 引发洪水错误
- python - Python脚本找不到文件
- docker - 无法在 Windows 10 上安装 Docker
- php - 如何在 laravel 中为管理员和其他人单独登录?
- javascript - 议程作业库,如何在每个月的最后一天午夜或一天的最后一分钟执行 cron
- sql - 如何选择包含最大数量的不同值的列名?- 甲骨文 SQL
- deep-learning - 将 pb 文件转换为 tflite 文件以在 Coral 开发板上运行(分段错误(核心转储))
- java - 有没有一种方法可以检查是否检测到哈希集(Java)的重复输入?
- c++ - 在 Linux 的 QT C++ 中设置 QButtons 的透明度