Vit*_*meo 3 c++ lambda types c++11 c++14
假设我有一些lambda具有完全相同的捕获和完全相同的签名.
int captured;
auto l0 = [&captured](int x){ captured += x; };
auto l1 = [&captured](int x){ captured -= x; };
auto l2 = [&captured](int x){ captured = x + 1; };
Run Code Online (Sandbox Code Playgroud)
现在,假设我需要将这些lambdas存储在一个std::vector,在运行时调用它们.
我不能使用原始函数指针,因为捕获的变量强制lambda成为仿函数,而不是传统函数.
我可以使用std::function,但它太过分了,因为我确信所有的lambda都有相同的签名和相同的捕获.由于std::function支持具有相同签名但不同捕获的 lambda ,我(很可能)支付额外的运行时成本,可以避免(?).
std::vector<decltype(l0)> v0; // Ok
v0.emplace_back(l0); // Ok
v1.emplace_back(l1); // Nope: `decltype(l0) != decltype(l1)`
v2.emplace_back(l2); // Nope: `decltype(l0) != decltype(l2)`
Run Code Online (Sandbox Code Playgroud)
我想要找到所有lambda之间的共同类型,但std::common_type不起作用.
// Nope: does not compile
using LCT = std::common_type_t<decltype(l0), decltype(l1), decltype(l2)>;
Run Code Online (Sandbox Code Playgroud)
基本上,我需要原始函数指针和之间的东西std::function.这样的事情存在吗?并且......可以实际实现这样的东西吗?
C++标准部分§5.1.2[expr.prim.lambda]:
lambda表达式的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型 - 称为闭包类型
每个lambda都有不同的类型:l0,l1并且l2没有通用类型.
因此,请考虑std::vector<>一种变体类型,例如boost.variant(如果你知道lambda类型的集合),或者使用std::function<>,这在这里也是合适的.
使用boost :: variant的示例:
int main () {
int captured = 42;
auto l0 = [&captured](int x){ captured += x; };
auto l1 = [&captured](int x){ captured -= x; };
auto l2 = [&captured](int x){ captured = x + 1; };
std::vector<boost::variant< decltype(l0), decltype(l1), decltype(l2)>> variant;
variant.push_back(l0);
variant.push_back(l1);
variant.push_back(l2);
auto f = boost::get<decltype(l1)>(variant[1]);
int i = 1;
f(i);
std::cout << captured;
}
Run Code Online (Sandbox Code Playgroud)
注意:
正如Johannes Schaub所指出的,像这样的lambda变体不是默认的可构造的,即你不能写:
boost::variant< decltype(l0), decltype(l1), decltype(l2)> v;
Run Code Online (Sandbox Code Playgroud)
而std::function<>默认是可构造的......
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |