服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++访问者模式模板函数无法重载的问题解决

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

2022-07-27 09:41Erick_Lv C/C++

本文主要介绍了C++访问者模式模板函数无法重载的问题解决,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

背景

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

参数的方法,比如:

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

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

解决方案

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

最终代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#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++访问者模式模板函数无法重载的问题解决的文章就介绍到这了,更多相关C++模板函数无法重载内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/7044478763312087053

延伸 · 阅读

精彩推荐
  • C/C++c语言_构建一个静态二叉树实现方法

    c语言_构建一个静态二叉树实现方法

    下面小编就为大家带来一篇c语言_构建一个静态二叉树实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    jingxian11972021-05-13
  • C/C++C语言之free函数以及野指针介绍

    C语言之free函数以及野指针介绍

    以下是对C语言中的free函数与野指针进行了详细的分析介绍,需要的朋友可以参考下...

    C语言教程网4002020-12-17
  • C/C++详解C++11 变参模板

    详解C++11 变参模板

    这篇文章主要介绍了C++11 变参模板的相关资料,帮助大家更好的理解和学习c++11,感兴趣的朋友可以了解下...

    Dabelv11322021-09-26
  • C/C++异步http listener 完全并发处理惩罚http恳求的小例子

    异步http listener 完全并发处理惩罚http恳求的小例子

    异步http listener 完全并发处理惩罚http恳求的小例子,需要的朋友可以参考一下...

    C语言教程网4172020-12-06
  • C/C++C++实现访问者模式的基础介绍

    C++实现访问者模式的基础介绍

    访问者模式表示一个作用于某对象结构中各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。对C++访问者模式相关知...

    herryone12310332022-01-10
  • C/C++C++顺序表实现图书管理系统

    C++顺序表实现图书管理系统

    这篇文章主要为大家详细介绍了C++顺序表实现图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Doraemon0212124002022-01-21
  • C/C++C++计算ICMP头的校验和实例

    C++计算ICMP头的校验和实例

    这篇文章主要介绍了C++计算ICMP头的校验和的方法,代码简单实用,对于校验ICMP报文来说有不错的实用价值,需要的朋友可以参考下...

    C++教程网5722021-02-14
  • C/C++c语言实现http下载器的方法

    c语言实现http下载器的方法

    这篇文章主要介绍了c语言实现http下载器的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    锅锅是锅锅9622021-12-08