是否可以访问(只读)lambda捕获的变量?

use*_*269 15 c++ c++11

是否可以访问(只读)lambda捕获的变量?

这不起作用:

std::function<double  (const double)> plus (const double a) {
    return [a] (const double b) -> double {
        return a+b;
    };
}

auto plus5 = plus(5);
cout << plus5.a << endl;
Run Code Online (Sandbox Code Playgroud)

Yak*_*ont 16

auto plus( double a ) {
  using R = struct {
    double a;
    double operator()(double b)const{return b+a;}
  };
  return R{std::move(a)};
}
Run Code Online (Sandbox Code Playgroud)

实例.

请注意,a std::function不是lambda,而lambda不是lambda std::function.他们互相合作,但使用一个术语来指向另一个是有用的.

  • @ user357269不需要.`std :: function`正常工作.魔法.噗.挥动你的手,看着它发生.如果你想知道幕后发生了什么,请阅读[type erasure](https://stackoverflow.com/documentation/c%2b%2b/2872/type-erasure#t=20160829133822308369). (3认同)

Com*_*sMS 14

这不是lambda应该如何使用.

lambda的接口是它的函数签名.其捕获应被视为实现细节,并且对用户不可见.

如果要显式访问捕获,请编写自己的函数对象并相应地公开相应的数据成员:

struct MyPlus {
    double a;
    MyPlus(double x) : a(x) {}
    double operator()(const double b)
    {
        return a+b;
    }
};

auto plus5 = MyPlus(5);
std::cout << plus5.a;
Run Code Online (Sandbox Code Playgroud)

  • @ user357269是的.但这是一个非常具体的情况,lambda只是不适合处理.所以我担心回到更冗长,但更强大的通用方法是你最好的选择. (5认同)

Que*_*tin 9

"绝对不是在将它存储在std函数之后.没有它,我可以用C++ 17中的一个可怕的(但合法的)黑客来做.但是我会是一个可怕的人告诉你如何,因为你可能会使用它. " - Yakk

好吧,让我们减轻Yakk的业力; 这里是C++ 14解决方案的概念证明,你绝对不想放弃它:

auto magic = [a, b](auto &&... args) mutable -> decltype(auto) {
    return makeOverload(

        // Capture access boilerplate
        [&](cap_<0>) -> auto& { return a; },
        [&](cap_<1>) -> auto& { return b; },

        // Actual function
        [&](int p) {
            return "[" + std::to_string(a) + ", " + b + "](" + std::to_string(p) + ")";
        }

    )(std::forward<decltype(args)>(args)...);
};
Run Code Online (Sandbox Code Playgroud)

makeOverload采用任意数量的仿函数并将它们合并为一个仿函数.我从这篇博文中借用了这个想法,并在评论部分的帮助下使其真正起作用.

生成的仿函数用于在cap<N>标记和函数的实际参数之间进行标记分派.因此,调用magic(cap<0>)会导致它吐出相应的捕获变量,即a.当然,函数的实际行为仍然可以通过正常调用来访问magic(123).

作为奖励,外部lambda是mutable,并且捕获访问器通过引用返回:您实际上对捕获的变量具有读写访问权限!

您可以在这里的 Coliru自然栖息地观察并与这种生物互动.