【发布时间】:2018-05-10 20:05:56
【问题描述】:
我正在开发一个库,它使用 lambda 来描述表达式术语的范围。因为库必须分发唯一的整数来标识每个变量,所以最好是由库而不是用户来构造变量,并且用户代码将它们作为 lambda 参数接收。
(换句话说,我正在从 miniKanren 实现“call\fresh”的 C++ 模拟。)
由于用户可能希望在特定范围内引入从零到许多新变量的任何数字,我希望用户能够将具有不同数量参数的 lambdas 传递给库。但是,我不知道有任何(简单)方法(在 C++14 中)来推断任意 lambda 对象的参数数量。
我突然想到为什么不将固定数量(例如 10)的可变 ID 参数传递给 lambda,并让用户代码在 lambda 中使用省略号来忽略不需要的参数?像这样的:
auto no_args = call_fresh([](...) { return success(); });
auto one_arg = call_fresh([](var A, ...) { return A == 1; });
auto two_args = call_fresh([](var A, var B, ...) { return A == 1 && B == 2; });
编译器资源管理器似乎接受 lambda 参数列表中的省略号,至少在 gcc 中是这样。
它会被这样调用(注意代码总是传递 10 个变量 id,无论“f”是只命名一个、两个还是一个都不命名):
template <typename F>
auto call_fresh(F f)
{
return [f](StateCounter sc) {
return f(sc+0,sc+1,sc+2,sc+3,sc+4,
sc+5,sc+6,sc+7,sc+8,sc+9);
};
}
我很惊讶它的存在,有什么理由不使用带有省略号的 lambdas 吗?
【问题讨论】:
-
variadic templates 或 initializer lists 是您想要的吗?
-
虽然可变参数模板可能会简化参数编号检测器,但它并不能解决(据我所知)这样的检测器目前仅适用于没有捕获的 lambda(因为只有它们有将它们衰减为函数指针的运算符)。至于初始化列表,它们会遇到所有参数必须具有相同类型的问题,并且我希望最终拥有不止一种类型的“var”。
标签: c++ lambda c++14 variadic-functions generic-lambda