8

我想知道,是否有办法获取捕获的 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_*<N>(lambda)显然应该导致编译器错误,当N > #captured_variables.

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

4

3 回答 3

16

这是设计不可能的

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

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

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

于 2013-11-14T11:38:53.137 回答
5

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

于 2013-11-14T01:08:05.563 回答
0

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

不过,您可以编写自己的函数对象。一个包含您要捕获的字段的结构和一个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;
}
于 2021-11-07T13:52:40.460 回答