【问题标题】:Get captured variables from lambda?从 lambda 获取捕获的变量?
【发布时间】:2013-11-26 14:25:17
【问题描述】:

我想知道,是否有办法获取捕获的 lambda 变量的类型/值? - 使用场景类似;

int a = 5;
auto lamb = [a](){ return a; };
static_assert(std::is_same<typename get_capture_type<0>(lamb)::type, int>::value, "");
assert(get_capture_value<0>(lamb) == 5)

注意:get_capture_*&lt;N&gt;(lambda) 显然会导致编译器错误,而 N &gt; #captured_variables

如果可能的话,我实际上需要的只是一种以某种方式访问​​捕获的方法。也就是说,我可以自己进行模板元编程。

【问题讨论】:

  • 编号。​​​​​​​​​​​​​​​​​​​​​​​​​​
  • 这种使用场景听起来不像任何真正的代码所需要的。
  • @Skeen:这和不能窥视我交给你的函数对象的私有变量有什么不同?
  • 为什么私有成员会在类本身之外产生任何影响?外界对我的实现细节没有任何断言。这不就是公共与私人的全部意义吗?
  • @Skeen:让我把这个问题转过来:您是否有任何用例表明知道捕获的内容很重要? lambda 或绑定对象或函子的全部目的是它实现的接口,如何调用它。它在调用时的作用对用户来说并不重要。如果您需要检查参数,请不要捕获它,将其作为参数传递,让调用者对其进行测试,然后使用它来调用 lambda。 (或者也可以编写自己的函子并提供所需的访问权限)

标签: c++ c++11 lambda c++14


【解决方案1】:

这是不可能的设计

5.1.2 [expr.prim.lambda]
15 [...] 对于复制捕获的每个实体,在闭包类型中声明了一个未命名的非静态数据成员。这些成员的声明顺序是未指定的。 [...]
16 [...] 对于通过引用捕获的实体,是否在闭包类型中声明了其他未命名的非静态数据成员,这一点尚未明确。

捕获的变量是未命名的(或者至少具有凡人无法说出的名称),并且它们的声明顺序是故意未指定的。闭包类型中的引用捕获甚至可能不存在

无论如何,您都不想这样做。你可能认为你有,但你不是真的。

【讨论】:

  • 这是我一直在寻找的答案。
【解决方案2】:

没有。 C++ 没有反射,这意味着它也没有对 lambda 的反射。

【讨论】:

    【解决方案3】:

    正如其他答案中提到的,这可能是不可能的,因为 lambda 字段是未命名的

    不过,您可以编写自己的函数对象。包含您要捕获的字段和 operator() 的结构。

    在你的情况下,我怀疑以下方法会起作用:

    #include <cassert>
    #include <type_traits>
    
    struct mylambda {
        int a;
        int operator()() { return a; }
    };
    
    int main()
    {
        int a = 5;
        auto lamb = mylambda{a};
        static_assert(std::is_same<decltype(lamb.a), int>::value, "");
        assert(lamb.a == 5);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多