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函数
[=,¶mx] :表示paramx是引用,其他的是形参
specifiers 说明
限定符值为mutable,含义是可以在函数体内修改按值捕获的变量;如果不需要此操作,则可以省略。
exception说明
异常说明符值为noexcept,含义是表达式不会抛出异常;如果不需要此操作,则可以省略。
Lambda表达式的优缺点
Lambda表达式有以下优点:
-
简洁:Lambda表达式可以在一个表达式中定义一个函数,不需要单独声明和定义。
-
方便:Lambda表达式可以捕获外部变量,使得函数对象更加灵活和易于使用。
-
通用:Lambda表达式可以作为任何需要函数对象的地方使用,例如STL算法、线程等。
Lambda表达式也有一些缺点:
-
可读性:Lambda表达式可能过于简洁,难以阅读和理解。
-
复杂性:Lambda表达式可以包含复杂的逻辑和控制流,使得代码难以维护和调试。
-
性能: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应用开发。欢迎合作。