文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何解决C++访问者模式模板函数无法重载的问题

2023-06-22 04:52

关注

本篇内容主要讲解“如何解决C++访问者模式模板函数无法重载的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决C++访问者模式模板函数无法重载的问题”吧!

背景

最近遇到一个比较棘手的场景,我们有一堆模块,他们有一个通用的基类,我们不防假设为 BaseClass,该类有一些通用的结构以及需要重载的方法。这些模块有一个堆同名但是不同类型

参数的方法,比如:

int DerivedClass1::DoNlpTask(const DerivedReq1& req, DerivedResp* resp);

类似这样的。每个 DerivedClass 的DoNlpTask都是同名不同参数的,而且这些要给业务去具体实现。正常来说,很容易想到函数重载的方式,但是很不幸,模板函数无法重载
但是,我们想让框架层和业务层相对解耦,不想让业务的具体类型等污染框架调度模块的结构。

解决方案

在这里,我们利用访问者模式的思想,结合C++的模板来统一处理。先定义一个Visitor,该类定义好具体业务模块的通用操作步骤;实现的时候利用模板特化来实例化不同的业务模块及其DoNlpTask 函数。这样在框架层只需要调用Visitor 的统一模板接口即可,具体参看一下代码。

最终代码

#include <iostream>#include <type_traits>// 以下模拟请求协议 =====================class BaseReq {};class DerivedReq : public BaseReq {};class BaseResp {};class DerivedResp : public BaseResp {};DerivedReq g_derived_req;// 以下模拟 NLP ============================class BaseClass { public:  // 单纯视为一个需要重载的函数  virtual int get_field_id() = 0;       virtual void WormUp () {}};#define REGISTER_PROTOTYPE(req_type, resp_type) \ public:                                        \  using ReqType = req_type;                     \  using RespType = resp_type;class DerivedClass : public BaseClass {  // 注册请求类型  REGISTER_PROTOTYPE(DerivedReq, DerivedResp) public:  int DoNlpTask(const DerivedReq&, DerivedResp* resp) {    std::cout << "Derived DoNlpTask\n";  }  int get_field_id() override { return 1; }};// 以下模拟pb反射 =========================const BaseReq* GetReqType() { return &g_derived_req; }// 以下是 visitor 的定义 ===========class Visitor { public:  template <typename ClassType>  int DoVisit(ClassType* base) {    static_assert(std::is_base_of<BaseClass, DerivedClass>::value,                  "type failed");    int idx = base->get_field_id();    std::cout << "visitor get field_id " << idx << std::endl;    const auto* req = GetMessageType<typename ClassType::ReqType>(GetReqType());    typename ClassType::RespType resp;    // 返回计算结果    return base->DoNlpTask(*req, &resp);  } private:  template <typename ReqType>  const ReqType* GetMessageType(const BaseReq* req) {    static_assert(std::is_base_of<BaseReq, ReqType>::value,                  "Message Type Error");    return static_cast<const ReqType*>(req);  }};int main() {  DerivedClass dc;  Visitor vis;  vis.DoVisit(&dc);  return 0;}

到此,相信大家对“如何解决C++访问者模式模板函数无法重载的问题”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯