You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化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);
}

方案说明

  1. 可变参数模板:typename... Args表示接收任意数量、任意类型的参数,C++11完全支持这个特性。
  2. 完美转发:std::forward<Args>(args)可以保留参数的左值/右值属性,避免不必要的对象拷贝,提升效率。
  3. 参数展开:利用int[]初始化列表和匿名lambda的方式,在C11中实现可变参数的逐个处理(C17的折叠表达式更简洁,但C++11只能用这种方式)。
  4. 逻辑复用:完全保留了你原有的Command构造、序列化、发送逻辑,只是简化了参数处理部分。

这个方案完全满足你的需求:调用方式简洁,代码无冗余,兼容C++11,同时支持任意数量的参数。

内容的提问来源于stack exchange,提问作者Danny Diaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:27:26