简体   繁体   English

将指向lambda函数的指针指定给指向另一个lambda函数的指针

[英]Assigning pointer to lambda function to pointer to another lambda function

I am trying to assign a pointer to lambda function to pointer to another lambda function. 我试图指定一个指向lambda函数的指针指向另一个lambda函数。 The code will speak for itself: 代码将说明一切:

#include <iostream>

int main(int argc, char *argv[]) {

    auto l1 = []() { std::cout << "Lambda 1!" << std::endl; };
    auto l2 = [] { std::cout << "Lambda 2!" << std::endl; };

    auto l1p = &l1;
    l1p = &l2; // Why can't I do this assignment?
    return 0;
}

Since the return types and argument of both lambda functions are the same, why can't I do this assignment? 由于两个lambda函数的返回类型和参数是相同的,为什么我不能做这个赋值?

[expr.prim.lambda]/2: [expr.prim.lambda] / 2:

The type of the lambda-expression (which is also the type of the closure object) is a unique , unnamed non-union class type — called the closure type — whose properties are described below. lambda表达式的类型(也是闭包对象的类型)是一个唯一的 ,未命名的非联合类类型 - 称为闭包类型 - 其属性如下所述。

That is, two closure types are always entirely distinct and unrelated. 也就是说,两种闭包类型总是完全不同且不相关。 However, in your example, as neither of both lambdas captures anything, they can be converted to a function pointer of type void(*)() . 但是,在您的示例中,由于两个lambda都没有捕获任何内容,因此可以将它们转换为void(*)()类型的函数指针。
So perhaps you meant to do 所以也许你打算做

void (*l1p)() = l1;
l1p = l2;

As an addition to Columbo's answer , you can have both type deduction and lambda-to-function-pointer decaying by using operator + : 作为Columbo答案的补充,你可以使用operator +同时进行类型推导和lambda-to-function指针衰减:

auto l1p = +l1; // l1p is void (*)()
//         ^
l1p = l2;

Let's remove the syntactic sugar that the lambda functions provide us: 让我们删除lambda函数为我们提供的语法糖:

struct lambda1 {
  void operator () {
    std::cout << "Lambda 1!" << std::endl;
  }
};
struct lambda2 {
  void operator () {
    std::cout << "Lambda 2!" << std::endl;
  }
};
int main(int argc, char *argv[]) {

    auto l1 = Lambda1{};
    auto l2 = Lambda2{};

    auto l1p = &l1; // l1p is a Lambda1 *
    l1p = &l2; // &l2 is a Lambda2 *
    return 0;
}

This isn't the exact transformation done by the compiler, but I think it suffices to examine the issue: 这不是编译器完成的转换,但我认为检查问题就足够了:

The two lambdas have each an own type, that is totally unrelated to their arguments, captured variables or return type. 这两个lambda都有自己的类型,与它们的参数,捕获的变量或返回类型完全无关。 And of course, the types of lambdas are to each other unrelated, so you can obviously not assign a pointer to one from the address of the other. 当然,lambda的类型彼此无关,所以你显然不能从另一个的地址指定一个指针。


The solution in the other answer with the function pointer is pretty nice. 使用函数指针解决另一个问题的解决方案非常好。 If there weren't a "you only pay for it when you use it" doctrine for C++, we could have made lambda functions like 如果C ++没有“你只用它为它付钱”的学说,我们就可以把lambda函数做成像

struct SomeLambda
  : public LambdaBase<
        Capture<int>,
        Arguments<bool>,
        Return<void>> {
  // ...
};
/*
  [integer]
  (bool flag) {
    if (flag) cout << integer;
  }
*/

But for that to make any sense the base would need to be polymorphic (has a virtual member function), and that's a cost you don't need if you don't intend to do what you wanted. 但是为了理所当然,基础需要是多态的(具有虚拟成员函数),如果你不打算做你想做的事情,这是你不需要的成本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM