gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 13:00:00 27 4
gpt4 key购买 nike

使用 std::function,我们可以使用 argument_typesecond_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);

但它不能直接与 lambdas 一起工作:

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

有没有一种方法可以同时适用于 lambda 和 std::function 对象来访问参数类型?也许有一种方法可以先获取 lambda 的 std::function 类型,然后从中获取 argument_type


根据下面的答案,可以使用 lambda 和 std::function 的版本是:

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); });

因为 int 在这里重复,我希望摆脱它 - 对于 int 来说不是那么糟糕,但对于几个命名空间中的长命名类型来说更烦人。 C'est la vie!

最佳答案

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

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

但是,我们有充分的理由从 C++0x 开始。其中最简单的就是简单的重载:一个带有模板化 operator() 的仿函数类型。 (a.k.a 多态仿函数)简单地接受所有类型的参数;那么应该怎么办argument_type是?另一个原因是泛型代码(通常)会尝试对其操作的类型和对象指定最少的约束,以便更容易(重新)使用。

换句话说,对于给定的 Functor f,通用代码真的不感兴趣, typename Functor::argumentint .知道 f(0)有趣是一个可以接受的表达。为此,C++0x 提供了诸如 decltype 之类的工具。和 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;
};

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

关于c++ - 我们能得到 lambda 参数的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44595687/

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