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

时间:2015-08-31 10:05:26

标签: c++ pointers c++11 lambda

我正在尝试将指向lambda函数的指针指向另一个lambda函数。代码将说明一切:

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

由于两个lambda函数的返回类型和参数是相同的,为什么我不能做这个赋值?

3 个答案:

答案 0 :(得分:16)

[expr.prim.lambda] / 2:

  

lambda-expression 的类型(也是其类型)   closure object)是一个唯一的,未命名的非联合类类型 - 被调用   闭包类型 - 其属性如下所述。

也就是说,两种闭包类型总是完全不同且不相关。但是,在您的示例中,由于两个lambda都没有捕获任何内容,因此可以将它们转换为void(*)()类型的函数指针。 所以也许你打算这样做

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

答案 1 :(得分:9)

作为Columbo's answer的补充,您可以使用operator +同时使用类型推导和lambda-to-function指针衰减:

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

答案 2 :(得分:7)

让我们删除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;
}

这不是编译器完成的确切转换,但我认为检查问题就足够了:

这两个lambda都有自己的类型,与它们的参数,捕获的变量或返回类型完全无关。当然,lambda的类型彼此不相关,所以你显然不能从另一个地址指定一个指针。

使用函数指针的另一个答案的解决方案非常好。如果没有&#34;你只需在使用它时支付费用&#34;对于C ++的学说,我们可以使lambda函数像

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

但是为了让它有任何意义,基础需要是多态的(具有虚拟成员功能),如果你不打算做什么,你就不需要付出代价你想要的。