gpt4 book ai didi

c++ - 如何获取 C++ bind(...) 表达式的签名

转载 作者:可可西里 更新时间:2023-11-01 15:08:06 26 4
gpt4 key购买 nike

我正在尝试编写一个名为 signature_of 的元函数,给定函数(指针)、仿函数或 lambda 的类型,返回其签名。

这是我目前所拥有的:

#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/parameter_types.hpp>

#include <type_traits>

template <typename F>
struct signature_of_member
{
typedef typename boost::function_types::result_type<F>::type result_type;
typedef typename boost::function_types::parameter_types<F>::type parameter_types;
typedef typename boost::mpl::pop_front<parameter_types>::type base;
typedef typename boost::mpl::push_front<base, result_type>::type L;
typedef typename boost::function_types::function_type<L>::type type;
};

template <typename F, bool is_class>
struct signature_of_impl
{
typedef typename boost::function_types::function_type<F>::type type;
};

template <typename F>
struct signature_of_impl<F, true>
{
typedef typename signature_of_member<decltype(&F::operator())>::type type;
};

template <typename F>
struct signature_of
{
typedef typename signature_of_impl<F, std::is_class<F>::value>::type type;
};

它非常简单,大部分实际工作由 boost::function_types 库完成。总体思路是:

  • 使用 std::is_class 来区分内置函数之间(包括lambdas) 和仿函数
  • 对于内置函数类型,使用 boost::function_types::function_type 获取其签名
  • 对于仿函数,获取其 operator() 的类型,获取其签名,并修改它以删除“this”参数

这适用于内置函数:

int f(int);
typedef signature_of<decltype(f)>::type Sig; // Sig is int(int)

对于 lambda:

auto f = [](int) { return 0; }
typedef signature_of<decltype(f)>::type Sig; // Sig is int(int)

对于仿函数:

struct A
{
int operator()(int);
};
typedef signature_of<A>::type Sig; // Sig is int(int)

但是,它不适用于 bind() 表达式(这是仿函数的特例)。如果我尝试这样做:

#include <functional>
int g(int);
typedef signature_of<decltype(std::bind(g, 0))>::type Sig;

我得到一个编译器错误:

In file included from test.cpp:3:0:
signature_of.hpp: In instantiation of 'signature_of_impl<
_Bind<int (*(int))(int)>, true
>':
signature_of.hpp:45:74: instantiated from 'signature_of<
_Bind<int (*(int))(int)>
>'
test.cpp:21:52: instantiated from here
signature_of.hpp:39:74: error: type of '& _Bind<
int (*)(int)({int} ...)
>::operator()' is unknown

问题是bind()返回的仿函数的operator()是一个模板,所以无法确定它的类型。

是否可以通过其他方式获取 bind() 表达式的签名?

最佳答案

您遇到的问题比 Binder 的 operator() 是模板化的事实还要多,它还有任意数量的参数。请记住,您应该能够使用任意数量的额外参数调用 bind 的结果。例如:

int f(int);

auto bound = boost::bind(f, _2);

bound 现在可以使用 2 个或更多的任意数量的参数调用,只有第二个实际转发到函数。

所以基本上,正如另一个答案所说,这个对象没有签名。它的签名仅由它的使用方式定义。

关于c++ - 如何获取 C++ bind(...) 表达式的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4771417/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com