什么是c ++ 11 / 1y lambda函数的类型签名? [英] what is the type signature of a c++11/1y lambda function?

查看:134
本文介绍了什么是c ++ 11 / 1y lambda函数的类型签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有一个标准的方法来获取任何给定lambda的参数的类型签名(即返回类型和类型)?

I was wondering if there is a standard way to get the type signature (i.e. the return type and the types) of its parameters of any given lambda?

我问的原因是我一直想知道在类型 auto code> auto l = [](int x,int y) - > int {return x + y;} 。在 auto 的其他用例中,对于较长的类型名称,这是一个方便和较短的选择。但是对于lambdas,是否有一种替代方法来声明lambda变量?

The reason I ask is that I've always wondered what exactly is the type auto in the declaration like auto l =[](int x,int y)->int{return x+y;}. In other use cases of auto, it's a convenience and shorter alternative for a longer type name. But for lambdas, is there even an alternative way to declare the lambda variable?

我的理解是,标准lambda只是一个函数对象,它是自己的类型。所以,即使两个lambdas有相同的返回类型和参数类型,它们仍然是两个不同的,不相关的类/函子。但是这有一种方法来捕获它们在类型签名方面是相同的事实?

My understanding is that a standard lambda is nothing more than a function object, and it is its own type. So, even if two lambdas have the same return type and parameter types, they are still two different, unrelated classes/functors. But this there a way to capture the fact that they are the same in terms of type signature?

我想我正在寻找的类型签名可以是一个类似 std :: function<> 正确类型的对象。

I think the type signature I am looking for can be something like a std::function<> object of the correct types.

可能提取类型签名,可以编写一个通用的包装函数将任何lambda函数转换为相同类型签名的 std :: function 对象。

A more useful/involved question is, if it's possible to extract the type signature, this is possible to write a general wrapper function to convert any lambda function to a std::function object of the same type signature.

推荐答案

根据,实际上在当前的c ++中有一个简单的方法(不需要c ++ 1y)输出lambda的return_type和参数类型。适应这一点,不难为每个组合一个 std :: function 类型签名类型(下面称为 f_type lambda。

According to Can the 'type' of a lambda expression be expressed?, there is actually a simple way in current c++ (without needing c++1y) to figure out the return_type and parameter types of a lambda. Adapting this, it is not difficult to assemble a std::function typed signature type (called f_type below) for each lambda.

我。对于这种抽象类型,实际上可以有一种替代方式 auto 用于表示lambda的类型签名,即 function_traits< ..> ; :: f_type 。注意: f_type 不是lambda的真实类型,而是功能术语中lambda的类型签名的摘要。然而,它可能比实际类型的lambda更有用,因为每个单独的lambda是它自己的类型

I. With this abstract type, it is actually possible to have an alternative way to auto for expressing the type signature of a lambda, namely function_traits<..>::f_type below. Note: the f_type is not the real type of a lambda, but rather a summary of a lambda's type signature in functional terms. It is however, probably more useful than the real type of a lambda because every single lambda is its own type.

如代码所示下面,就像可以使用 vector< int> :: iterator_type i = v.begin(),也可以做 function_traits< lambda> ;: :f_type f = lambda ,这是神秘 auto 的替代方法。当然,这种相似性只是形式化的。下面的代码涉及将 std :: function 转换为 std :: function c>对象和通过 std :: function 对象进行间接调用的成本很小。但这些实现问题使用 std :: function aside(我不认为是根本的,应该永远),毕竟,有可能明确表达(抽象)任何给定lambda的签名。

As shown in the code below, just like one can use vector<int>::iterator_type i = v.begin(), one can also do function_traits<lambda>::f_type f = lambda, which is an alternative to the mysterious auto. Of course, this similarity is only formal. The code below involves converting the lambda to a std::function with the cost of type erasure on construction of std::function object and a small cost for making indirect call through the std::function object. But these implementation issues for using std::function aside (which I don't believe are fundamental and should stand forever), it is possible, after all, to explicitly express the (abstract) type signature of any given lambda.

II。也可以写一个 make_function 包装器(很像 std :: make_pair std :: make_tuple )自动将lambda f (和其他可调用函数,如函数指针/函子)转换为 std: :function ,具有相同的类型扣除功能。

II. It is also possible to write a make_function wrapper (pretty much like std::make_pair and std::make_tuple) to automatically convert a lambda f ( and other callables like function pointers/functors) to std::function, with the same type-deduction capabilities.

测试代码如下:

#include <cstdlib>
#include <tuple>
#include <functional>
#include <iostream>
using namespace std;

// For generic types that are functors, delegate to its 'operator()'
template <typename T>
struct function_traits
    : public function_traits<decltype(&T::operator())>
{};

// for pointers to member function
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const> {
    //enum { arity = sizeof...(Args) };
    typedef function<ReturnType (Args...)> f_type;
};

// for pointers to member function
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) > {
    typedef function<ReturnType (Args...)> f_type;
};

// for function pointers
template <typename ReturnType, typename... Args>
struct function_traits<ReturnType (*)(Args...)>  {
  typedef function<ReturnType (Args...)> f_type;
};

template <typename L> 
typename function_traits<L>::f_type make_function(L l){
  return (typename function_traits<L>::f_type)(l);
}

long times10(int i) { return long(i*10); }

struct X {
  double operator () (float f, double d) { return d*f; } 
};

// test code
int main()
{
    auto lambda = [](int i) { return long(i*10); };
    typedef function_traits<decltype(lambda)> traits;
    traits::f_type ff = lambda;

    cout << make_function([](int i) { return long(i*10); })(2) << ", " << make_function(times10)(2) << ", " << ff(2) << endl;
    cout << make_function(X{})(2,3.0) << endl;

    return 0;
}

这篇关于什么是c ++ 11 / 1y lambda函数的类型签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆