C++ 如何获得C+的签名+;bind(…)表达式

C++ 如何获得C+的签名+;bind(…)表达式,c++,function,boost,c++11,signature,C++,Function,Boost,C++11,Signature,我试图编写一个名为signature_的元函数,给定函数(指针)、函子或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_ty

我试图编写一个名为signature_的元函数,给定函数(指针)、函子或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;
};
#包括
#包括
#包括
#包括
#包括
#包括
#包括
模板
成员的结构签名
{
typedef typename boost::函数类型::结果类型::类型结果类型;
typedef typename boost::函数类型::参数类型::类型参数类型;
typedef typename boost::mpl::pop_front::type base;
typedef typename boost::mpl::push_front::type L;
typedef typename boost::函数类型::函数类型::类型类型;
};
模板
结构签名\u的\u impl
{
typedef typename boost::函数类型::函数类型::类型类型;
};
模板
结构签名\u的\u impl
{
typedef typename成员的签名:type type;
};
模板
结构签名
{
typedef typename签名\u impl::type类型;
};
这非常简单,大部分实际工作都是由boost::function_类型库完成的。 总的想法是:

  • 使用std::is_类进行区分 内置功能之间(包括 lambdas)与函子
  • 对于内置函数类型,使用boost::function\u types::function\u type获取其签名
  • 对于函子,获取其运算符()的类型,获取其签名,并对其进行修改以删除“this”参数
这适用于内置功能:

int f(int);
typedef signature_of<decltype(f)>::type Sig;  // Sig is int(int)
intf(int);
typedef signature_of::type Sig;//Sig是int(int)
对于lambdas:

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

struct A
{
    int operator()(int);
};
typedef signature_of<A>::type Sig;  // Sig is int(int)
结构A { int运算符()(int); }; typedef signature_of::type Sig;//Sig是int(int) 但是,它不适用于bind()表达式(这是函子的特例)。如果我尝试这样做:

#include <functional>
int g(int);
typedef signature_of<decltype(std::bind(g, 0))>::type Sig;
#包括
int g(int);
typedef签名_of::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
test.cpp:3:0中包含的文件中的
:
signature\u of.hpp:在“signature\u of\u impl”的实例化中<
_绑定,真的
>':
.hpp的签名:45:74:从“的签名”实例化<
_束缚
>'
test.cpp:21:52:从此处实例化
.hpp的签名:39:74:错误:类型为“&”<
int(*)(int)({int}…)
>::运算符()未知
问题是bind()返回的函子的运算符()是模板,因此无法确定其类型


有没有可能以另一种方式获取bind()表达式的签名?

如果操作符是模板化的,那么它就没有签名。

您遇到的问题不仅仅是binder的操作符()是模板化的,它还有任意数量的参数。请记住,您应该能够使用任意数量的额外参数调用bind的结果。例如:

int f(int);

auto bound = boost::bind(f, _2);
bound
现在可以使用任意数量的2个或更多参数调用,只有第二个参数实际被转发到函数


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

或者从稍微不同的角度来看,它没有唯一的签名
operator()
可以用不同的模板参数实例化,它们参与了
operator()
实例化的签名。是的,但是如果g有签名int(int),那么从概念上讲,bind(g,0)应该有签名int(void)。std::bind实现使用模板运算符()的事实只是一个实现细节。@HighCommander4:从概念上讲?谁在乎呢?事实是,这不会发生。如果
bind
生成了一个带有模板操作符()的函子,那么你就完蛋了,你可以随心所欲地构思任何概念,它不会改变这一点。当然,通过检查操作符()是没有办法的,但也许还有另一种方法,例如,通过检查bind()返回的对象的模板参数@HighCommander4:MSDN表示返回类型未指定,只保证它提供
结果\u type
typedef。事实上,必须对运算符()进行模板化,以便完美地转发其参数。我刚刚检查了MSVC10,它认为返回类型本质上没有任何有用的东西。VC10无法编译它,错误通常都很愚蠢(
error C2039:'type':不是'boost::function\u types::result\u type'
),它不喜欢这种专门化:
typedef typename signature\u of_member::type
@Andy T:如果不提到std::function的模板参数,即签名,如何转换为std::function?很好,我其实不知道你可以这样使用bind()。