如何优化C++可变参数成员函数?(兼容C++11及更早版本)
重构C++11下的可变参数远程函数调用
针对你想要简化CallRemoteFunction的需求,在C++11环境下,可变参数模板+完美转发是最适合的方案,既能实现你想要的简洁调用方式,又能避免原代码的冗余参数列表。下面是具体的实现思路和代码:
核心方案:可变参数模板函数
因为你已经明确函数不必是虚函数,我们可以直接用C++11支持的可变参数模板来接收任意数量、任意类型的参数,然后逐个转换为OVariant并处理。
实现代码
#include <utility> // 用于std::forward // 可变参数模板版本的CallRemoteFunction template<typename... Args> void Peer::CallRemoteFunction(const char* pServerGameObjectId, const char* pFunctionName, Args&&... args) { Command command; command.SetObjectName(pServerGameObjectId); command.SetFunctionName(pFunctionName); command.ResetArgs(); // 利用C++11的初始化列表展开可变参数 // 用匿名lambda处理每个参数,转换为OVariant后判断有效性并Push using expander = int[]; (void)expander{0, ( [&](){ // 完美转发参数,避免不必要的拷贝 OVariant var(std::forward<Args>(args)); if (var.IsValid()) { command.PushArg(var); } }(), 0)...}; // 保留你原有的日志、序列化、发送逻辑 LOG_DEBUG("Calling Remote Function : " << pServerGameObjectId << "." << command.GetFunctionName()); ByteArray buffer(command.GetSerializeSize()); command.Serialize(buffer); ZMQMessage* request = new ZMQMessage(); // deleted when sent via zmq request->addmem(buffer.GetBytes(), buffer.m_NumBytes); PushMessage(MDPW_REQUEST, m_pServiceId, request); }
调用方式
现在你可以像这样简洁地调用:
// 无额外参数 peer->CallRemoteFunction("serverID", "someFunc"); // 多个不同类型参数(只要OVariant支持对应类型的构造) peer->CallRemoteFunction("serverID", "someFunc", 1, "hello", 3.14f);
兼容性处理(可选)
如果你需要保留原有的多参数重载(比如兼容旧代码调用),可以让原函数直接调用新的可变参数版本:
// 原有的冗余参数版本,现在作为适配层 void Peer::CallRemoteFunction(const char* pServerGameObjectId, const char* pFunctionName, OVariant arg1, OVariant arg2, OVariant arg3, OVariant arg4, OVariant arg5, OVariant arg6, OVariant arg7, OVariant arg8, OVariant arg9) { // 直接转发到可变参数版本 CallRemoteFunction(pServerGameObjectId, pFunctionName, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }
方案说明
- 可变参数模板:
typename... Args表示接收任意数量、任意类型的参数,C++11完全支持这个特性。 - 完美转发:
std::forward<Args>(args)可以保留参数的左值/右值属性,避免不必要的对象拷贝,提升效率。 - 参数展开:利用
int[]初始化列表和匿名lambda的方式,在C11中实现可变参数的逐个处理(C17的折叠表达式更简洁,但C++11只能用这种方式)。 - 逻辑复用:完全保留了你原有的Command构造、序列化、发送逻辑,只是简化了参数处理部分。
这个方案完全满足你的需求:调用方式简洁,代码无冗余,兼容C++11,同时支持任意数量的参数。
内容的提问来源于stack exchange,提问作者Danny Diaz
相关产品推荐
相关产品推荐

