我们能得到 lambda 参数的类型吗?

2023-12-29

Using std::function,我们可以使用以下方法获取参数的类型argument_type, second_argument_type等等 typedef,但我看不到用 lambda 做同样事情的方法。是否可以? (我用的是VS2010)

假设我想要在我的反序列化系统中使用类似以下内容来读取对象并将其传递给 setter 函数:

template<typename F> 
static void forward(F f)
{ 
    // Create an object of the type of the first
    // parameter to the function object F
    typedef typename F::argument_type T;
    T t;

    //...do something with 't' here (deserialize in my case)

    // Forward the object to the function
    f(t);
}

它可以像这样使用并且一切正常:

std::function<void(int)> f = [](int i) -> void { setValue(i); };
forward(f);

但它不能直接与 lambda 一起使用:

forward([](int i) -> void { setValue(i); });
//error C2039: 'argument_type' : is not a 
//member of '`anonymous-namespace'::<lambda1>'

有没有一种方法可以同时适用于 lambda 和std::function物体?也许有一种方法可以得到std::function首先是 lambda 的类型,然后是argument_type从那个?


继下面的答案之后,一个与 lambda 一起使用的版本和std::function is:

template<typename T, typename F> 
static void forward(F f)
{ 
    T t;

    //...do something with 't' here (deserialize in my case)

    f(t);
}

forward<int>([](int i) -> void { setValue(i); });

Since int在这里重复我希望摆脱它 - 对于int但对于几个命名空间中的长命名类型来说更烦人。这就是生活!


在一般情况下这是不可取的。 (请注意,这很容易std::function<T(A)>指定什么,例如argument_type是:这只是A!它在类型定义中可用。)

可以要求每个函数对象类型指定其参数类型,并反过来要求从 lambda 表达式生成的闭包类型这样做。事实上,C++0x 之前的功能(例如自适应函子)仅适用于此类类型。

然而,我们正在通过 C++0x 来改变这一点,并且有充分的理由。其中最简单的就是重载:带有模板化的函子类型operator()(又名多态函子)简单地接受所有类型的参数;那么应该怎样做argument_type是?另一个原因是通用代码(通常)尝试对其操作的类型和对象指定最少的约束,以便更容易(重新)使用。

换句话说,通用代码不是really有兴趣给出Functor f, typename Functor::argument be int. It's 多得多有趣的是f(0)是一个可以接受的表达方式。为此,C++0x 提供了诸如decltype and std::declval(方便地将两个包装在里面std::result_of).

在我看来,您有两种选择: 要求传递给模板的所有函子都使用 C++03 风格的约定来指定argument_type等等;使用下面的技术;或重新设计。我推荐最后一个选项,但这是你的决定,因为我不知道你的代码库是什么样的,也不知道你的要求是什么。


对于单态函子类型(即无重载),可以检查operator()成员。这适用于 lambda 表达式的闭包类型。

所以我们声明这些助手

template<typename F, typename Ret, typename A, typename... Rest>
A
helper(Ret (F::*)(A, Rest...));

template<typename F, typename Ret, typename A, typename... Rest>
A
helper(Ret (F::*)(A, Rest...) const);

// volatile or lvalue/rvalue *this not required for lambdas (phew)

接受一个指向至少带有一个参数的成员函数的指针。现在:

template<typename F>
struct first_argument {
    typedef decltype( helper(&F::operator()) ) type;
};

[ 一个精心设计的特征可以连续查询左值-右值/常量/易失性重载,并公开第一个参数(如果它对于所有重载都相同),或者使用std::common_type.]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我们能得到 lambda 参数的类型吗? 的相关文章

随机推荐