c++ - 具有相同签名和捕获的常见 lambda 类型

标签 c++ c++11 types lambda 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; };

现在,假设我需要将这些 lambda 存储在 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)`

我想要找出所有 lambda 之间的公共(public)类型,但 std::common_type 不起作用。

// Nope: does not compile
using LCT = std::common_type_t<decltype(l0), decltype(l1), decltype(l2)>;

基本上,我需要介于原始函数指针和 std::function 之间的东西。 是否存在类似的东西?而且……这样的事情真的可以实现吗?

最佳答案

C++ 标准部分§ 5.1.2 [expr.prim.lambda]:

The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed non union class type — called the closure type

每个 lambda 都有不同的类型:l0 , l1l2没有共同的类型。

因此请考虑 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;
}

Demo

注意:

正如 Johannes Schaub 所指出的,像这样的 lambda 变体不是默认可构造的,即你不能写:

boost::variant< decltype(l0), decltype(l1), decltype(l2)> v;

std::function<>是默认可构造的..

关于c++ - 具有相同签名和捕获的常见 lambda 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28263207/

相关文章:

c++ - 带有 std::function 的通用 lambda 不捕获变量

c++ - 如何将 Base* 指针视为 Derived<T>* 指针?

java - 如何修改 void 类方法使其返回所需信息

c++ - 如何忽略无序映射/映射中的单个字符串值?

c++ - 使用索引与迭代器将 vector 迭代到倒数第二个元素

C++11 别名模板作为特化中的模板模板参数?

python - Cython:C 级 int 与 PyLongObjects

c++ - C++静态数据成员的实现

C++ 字符串流连接查询

c++ - 如何制作自定义关键字语句