6

当泛型 lambda 存储为 astd::function时,我们需要提供一个具体类型,例如,

std::function<double(double)>

因此绑定到特定类型,

以下声明:

std::function<auto(auto)>

引发编译器错误。

我知道,从 c++14 开始,auto可以用来存储 lambda 的返回值,但是在存储 lambda 时有没有办法实现这一点std::function

4

2 回答 2

4

你不能。甚至没有用自定义写的std::function。这是类型擦除的基本限制。

直观地说,模板需要在函数调用点可用的类型信息,但类型擦除std::function会破坏该信息。

在更详细的级别上,类型擦除通过在编译时以与类型无关的方式存储操作集来工作,无论是通过虚函数隐式还是通过函数指针显式存储。模板实际上是一个无限的操作族,因此不可能被存储。

如果您知道您将使用的一组固定的函数签名,您可以编写一个自定义的std::function.

于 2018-12-18T10:59:38.657 回答
2

你不能。

通用 lambda 和std::function是完全不同的东西。

您可以粗略地将auto(auto)lambda 视为带有 template 的非模板类operator()

某事作为

struct myUnnamedLambdaStruct
 {
   // ...

   template <typename T>
   auto operator() (T t) const 
    { /* .... */ };
 };

相反的地方std::function():它是一个(专门化的)模板类,带有一个非模板operator()

template <typename>
class function;

template <typename RetType, typename ... ArgTypes>
class function<RetType(ArgTypes...)>
 {
   // a lot of other members/methods

   public:
      RetType operator() (ArgTypes ... args) const
       { /* .... */ }
 };

因此,通用 lambda 对象不包含单个对象,而是包含operator()对象operator()包含std::function单个operator().

您可以在 a 中“保存”一个通用 lambda,std::function但只能一次性修复RetTypeArgTypes.... 即:operator()在可用的operator()s 集合中选择一个 ,然后忘记所有其他的。

于 2018-12-18T11:20:24.470 回答