温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-12-24 09:03:55 来源:亿速云 阅读:156 作者:iii 栏目:开发技术

本篇内容主要讲解“如何解决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++访问者模式模板函数无法重载的问题”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++
AI