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

现代C++如何不使用if/switch,根据命令类型查找对应命令处理程序

实现思路

核心是把类型匹配逻辑交给编译器静态分发/标准库实现,完全避免手动编写if/switch分支。下面给出两种主流的现代C++实现方案:

方案1:C++17及以上使用 std::variant + std::visit(推荐)

不需要继承公共基类,代码更简洁,运行时无额外开销:

#include <iostream>
#include <variant>

// 重载lambda辅助模板,用于多类型匹配
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

// 命令定义,不需要继承公共基类
struct CommandA
{
    int a = 32;
};

struct CommandB
{
    double b = 56.43;
};

// 处理器定义保持不变
class ACommandHandler
{
public:
    void Process(CommandA command) { std::cout << command.a; }
};

class BCommandHandler
{
public:
    void Process(CommandB command) { std::cout << command.b; }
};

// 命令类型集合定义
using Command = std::variant<CommandA, CommandB>;

class Intermediator
{
public:
    void Delegate(Command command)
    {
        // 标准库visit自动匹配对应类型的处理逻辑,无任何手动分支
        std::visit(overloaded{
            [this](CommandA cmd) { handlerA.Process(cmd); },
            [this](CommandB cmd) { handlerB.Process(cmd); }
        }, command);
    }

private:
    ACommandHandler handlerA;
    BCommandHandler handlerB;
};

int main()
{
    Intermediator intermediator;
    CommandA a;
    intermediator.Delegate(a); // 输出32
    CommandB b;
    intermediator.Delegate(b); // 输出56.43
    return 0;
}

方案2:访问者模式(兼容C++11/14)

如果需要兼容旧标准,可以用经典访问者模式实现动态分发:

#include <iostream>

class CommandVisitor;

// 基类增加访问者接口
struct Command
{
    virtual void Accept(CommandVisitor& visitor) = 0;
    virtual ~Command() = default;
};

struct CommandA;
struct CommandB;

class CommandVisitor
{
public:
    virtual void Visit(CommandA& cmd) = 0;
    virtual void Visit(CommandB& cmd) = 0;
};

struct CommandA : Command
{
    int a = 32;
    void Accept(CommandVisitor& visitor) override {
        visitor.Visit(*this);
    }
};

struct CommandB : Command
{
    double b = 56.43;
    void Accept(CommandVisitor& visitor) override {
        visitor.Visit(*this);
    }
};

// 处理器保持不变
class ACommandHandler
{
public:
    void Process(CommandA command) { std::cout << command.a; }
};

class BCommandHandler
{
public:
    void Process(CommandB command) { std::cout << command.b; }
};

// 中介类实现访问者接口
class Intermediator : public CommandVisitor
{
public:
    void Delegate(Command& command)
    {
        command.Accept(*this);
    }

    void Visit(CommandA& cmd) override {
        handlerA.Process(cmd);
    }

    void Visit(CommandB& cmd) override {
        handlerB.Process(cmd);
    }

private:
    ACommandHandler handlerA;
    BCommandHandler handlerB;
};

int main()
{
    Intermediator intermediator;
    CommandA a;
    intermediator.Delegate(a); // 输出32
    CommandB b;
    intermediator.Delegate(b); // 输出56.43
    return 0;
}

说明:整个流程完全没有手动判断类型的if/switch分支,分发逻辑由虚函数表的动态调用实现

内容的提问来源于stack exchange,提问作者Jarkness Ferture

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:27:03