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应用开发。欢迎合作。