C++如何通过lambda的auto参数类型声明外部作用域的对应变量
你的需求可以实现,以下是三种适配你当前uWebSockets场景的实现方案,均不需要硬编码WebSocket的模板参数,也不需要向lambda传递额外参数:
方案1:通过标准库工具直接推导类型
借助std::declval直接从uWS公开的类型定义推导出WebSocket指针类型,无运行时开销,是最推荐的方案:
#include <utility> using DataType = std::string; // 自动推导WebSocket指针类型,和lambda中auto* ws的类型完全一致 using WsPtrType = decltype(std::declval<uWS::App::WebSocketContext<DataType>>().getWebSocket()); static std::vector<WsPtrType> users;
方案2:模板工具函数自动推导
不需要在外部提前声明变量类型,所有类型和lambda参数自动对齐,适配性更强,升级uWS版本也不需要修改代码:
// 全局工具模板函数,调用时自动推导参数类型生成对应vector template <typename T> std::vector<T>& get_user_vec(T) { static std::vector<T> users; return users; } uWS::App app {}; app.ws<DataType>("/*", { .open = [](auto * ws){ get_user_vec(ws).push_back(ws); ws->subscribe("sensors/+/house"); }, .close = [](auto *ws, int code, std::string_view message){ auto& users = get_user_vec(ws); users.erase(std::remove(users.begin(), users.end(), ws), users.end()); std::cout << "Client disconnected!" << std::endl; }, .message = [](auto *ws, std::string_view message, uWS::OpCode opCode){ try{ std::string message2 = std::string(message) + std::string(" ACK"); auto& users = get_user_vec(ws); for(const auto & ws2 : users) if(ws != ws2) ws2->send(message2, opCode); }catch(std::exception& e){ std::cout << e.what() << std::endl; } }, });
方案3:类型擦除封装多回调共享上下文
如果后续有大量需要跨回调共享的变量,可以用std::any做类型擦除,完全不需要提前感知任何uWS相关类型:
#include <any> struct SharedContext { std::any users; } ctx; // open回调中完成一次初始化即可 .open = [](auto * ws){ if (!ctx.users.has_value()) { ctx.users = std::vector<decltype(ws)>{}; } auto& users = std::any_cast<std::vector<decltype(ws)>&>(ctx.users); users.push_back(ws); // 其他逻辑 }
内容的提问来源于stack exchange,提问作者nmd_07
相关产品推荐
相关产品推荐

