C++ Lambda函数

lambda语法

[capture list] (parameter list) specifiers exception -> type { function body }
  • [capture list]是捕获列表,在应用中必填。

  • (parameter list)是参数列表,在应用中选填。

  • specifiers是限定符,在应用中选填。

  • exception是异常说明符,在应用中选填。

  • -> type是返回值类型,在应用中选填。

  • { function body }是表达式的函数体,在应用中必填。

lambda表达式返回值类型;如果不指定返回类型,则编译器会根据代码实现为函数推导一个返回类型;如果没有返回值,则可忽略此部分。

[capture list]说明

关于中括号,有三种形式[],[&],[=],[=,&c](混合模式)

[]   : 当前作用域的参数不拷贝到lambda函数

[&] : 将当前作用域的变量作为引用传入lambda函数

[=]:  将当前作用域的变量作为形参传入lambda函数

[=,&paramx] :表示paramx是引用,其他的是形参

specifiers 说明

限定符值为mutable,含义是可以在函数体内修改按值捕获的变量;如果不需要此操作,则可以省略。

exception说明

异常说明符值为noexcept,含义是表达式不会抛出异常;如果不需要此操作,则可以省略。

Lambda表达式的优缺点

Lambda表达式有以下优点:

  1. 简洁:Lambda表达式可以在一个表达式中定义一个函数,不需要单独声明和定义。

  2. 方便:Lambda表达式可以捕获外部变量,使得函数对象更加灵活和易于使用。

  3. 通用:Lambda表达式可以作为任何需要函数对象的地方使用,例如STL算法、线程等。

Lambda表达式也有一些缺点:

  1. 可读性:Lambda表达式可能过于简洁,难以阅读和理解。

  2. 复杂性:Lambda表达式可以包含复杂的逻辑和控制流,使得代码难以维护和调试。

  3. 性能:Lambda表达式可能会产生额外的开销,例如变量捕获和函数调用的开销。

lambda声明

 Reader<Message> logger(kQueueName, [](const Message& data) {
    std::cout << "Received coordinate " << data << std::endl;
  });

测试代码

#include <fstream>
#include <iostream>
#include <thread>
#include <vector>

#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

std::string kQueueName = "/test2";

class MessageQueue {
  private:
    mqd_t handle;
  public:
    MessageQueue(const std::string& name, int flags) {
      handle = mq_open(name.c_str(), flags);
      if (handle < 0) {
        throw std::runtime_error("Failed to open a queue for writing");
      }
    }

    MessageQueue(const std::string& name, int flags, int max_count, int max_size) {
      struct mq_attr attrs = { 0, max_count, max_size, 0 }; 
      handle = mq_open(name.c_str(), flags | O_CREAT, 0666, &attrs);
      if (handle < 0) {
        throw std::runtime_error("Failed to create a queue");
      }
    }

    ~MessageQueue() {
      mq_close(handle);
    }

    void Send(const char* data, size_t len) {
      if (mq_send(handle, data, len, 0) < 0) {
        throw std::runtime_error("Failed to send a message");
      }
    }

    void Receive(char* data, size_t len) {
      if (mq_receive(handle, data, len, 0) < len) {
        throw std::runtime_error("Failed to receive a message");
      }
    }
};

template<class T>
class Writer {
  private:
    MessageQueue queue;
  public:
    Writer(std::string& name):
      queue(name, O_WRONLY) {}

    void Write(const T& data) {
      queue.Send(reinterpret_cast<const char*>(&data), sizeof(data));
    }
};

template<class T>
class Reader {
  private:
    MessageQueue queue;
    void (*func)(const T&);
  public:
    Reader(std::string& name, void (*func)(const T&)):
      queue(name, O_RDONLY), func(func) {}

    void Run() {
      T data;
      while(true) {
        queue.Receive(reinterpret_cast<char*>(&data), sizeof(data));
        func(data);
      }
    }
};

struct Message {
  int x, y;
};

std::ostream& operator<<(std::ostream& o, const Message& m) {
  o << "(x=" << m.x << ", y=" << m.y << ")";
}

void DoWrites() {
  std::vector<Message> messages {{1, 0}, {0, 1}, {1, 1}, {0, 0}};
  Writer<Message> writer(kQueueName);
  for (const auto& m : messages) { 
    std::cout << "Write " << m << std::endl;
    writer.Write(m);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  }
}

void DoReads() {
  Reader<Message> logger(kQueueName, [](const Message& data) {
    std::cout << "Received coordinate " << data << std::endl;
  });
  logger.Run();
}


int main(int argc, char** argv) {
  MessageQueue q(kQueueName, O_WRONLY, 10, sizeof(Message));
  pid_t pid = fork();
  if (pid) {
    DoWrites();
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    kill(pid, SIGTERM);
  } else {
    DoReads();
  }
}

我公司承接各类技术服务,主要聚焦于:stm32、单片机、嵌入式、QT应用开发、Web+Python+Django应用开发。欢迎合作。

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汉森教育

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值