effective c++ 43-处理模板化基类的名称 笔记

news/2024/11/23 20:42:57/

effective c++ 43-处理模板化基类的名称

该节主要分析了一个写模板时常常会遇到的一个编译错误。

分析

这里有一个模板基类,有派生类继承了模板基类,并调用了基类中的方法,但是编译器却会报找不该方法,这是怎么回事?

#include <string>
#include <iostream>
class CompanyA
{
public:void sendCleartext(const std::string& msg) {std::cout << "A sendCleartext" << std::endl;}void sendEncrypted(const std::string& msg) {std::cout << "A sendEncrypted" << std::endl;}
};class CompanyB
{
public:void sendCleartext(const std::string& msg) {std::cout << "B sendCleartext" << std::endl;}void sendEncrypted(const std::string& msg) {std::cout << "B sendEncrypted" << std::endl;}
};class MsgInfo {
public:MsgInfo(std::string msg):msg_(msg){}
private:std::string msg_{};
};template<typename Company>
class MsgSender
{
public:void sendClear(const MsgInfo& info){std::string msg;Company c;c.sendCleartext(msg);}void sendSecret(const MsgInfo& info){}
};template<typename Company>
class LoggingMsgSender : public MsgSender<Company>
{
public:void sendClearMsg(const MsgInfo& info){sendClear(info);}
};int main()
{MsgInfo info("test");LoggingMsgSender<CompanyB> loggingMsgSender;loggingMsgSender.sendClearMsg(info);
}

编译输出如下:

/home/work/cpp_proj/test2/main.cpp: In member function ‘void LoggingMsgSender<Company>::sendClearMsg(const MsgInfo&)’:
/home/work/cpp_proj/test2/main.cpp:63:9: error: there are no arguments to ‘sendClear’ that depend on a template parameter, so a declaration of ‘sendClear’ must be available [-fpermissive]sendClear(info);^~~~~~~~~
/home/work/cpp_proj/test2/main.cpp:63:9: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/home/work/cpp_proj/test2/main.cpp: In instantiation of ‘void LoggingMsgSender<Company>::sendClearMsg(const MsgInfo&) [with Company = CompanyB]’:
/home/work/cpp_proj/test2/main.cpp:71:39:   required from here
/home/work/cpp_proj/test2/main.cpp:63:18: error: ‘sendClear’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]sendClear(info);~~~~~~~~~^~~~~~
/home/work/cpp_proj/test2/main.cpp:63:18: note: declarations in dependent base ‘MsgSender<CompanyB>’ are not found by unqualified lookup
/home/work/cpp_proj/test2/main.cpp:63:18: note: use ‘this->sendClear’ instead

从编译的输出也可以看出,原因是编译器觉得sendClear含义不明确,编译器也给出了解决办法,使用this->sendClear,这里我们要思考的是,为什么编译器会找不到sendClear函数呢? 不是就定义在模板基类中吗?

实际上原因就是基类是一个模板类, 而模板类是可以被特化的,例如这里又有了一个CompanyZ,而MsgSender对于CompanyZ的特化版本可能就没有sendClear方法,因此编译器才会说sendClear含义不明确。

class CompanyZ
{
public:void sendEncrypted(const std::string& msg) {}
};template<>
class MsgSender<CompanyZ>
{
public:void sendSecret(const MsgInfo& info){}
};

好了,知道了原因之后,那么就可以给出解决办法了,其实上面编译器也已经给出来一种办法。

第一种就是在派生类中调用模板基类中的方法时加上this->

template<typename Company>
class LoggingMsgSender : public MsgSender<Company>
{
public:void sendClearMsg(const MsgInfo& info){this->sendClear(info);}
};

have a try

第二种就是在派生类中调用模板基类中的方法时加上使用using

template<typename Company>
class LoggingMsgSender : public MsgSender<Company>
{
using MsgSender<Company>::sendClear;public:void sendClearMsg(const MsgInfo& info){sendClear(info);}
};

have a try

第三种就是在派生类中明确指出使用MsgSender<Company>::sendClear(info)

template<typename Company>
class LoggingMsgSender : public MsgSender<Company>
{
public:void sendClearMsg(const MsgInfo& info){MsgSender<Company>::sendClear(info);}
};

have a try

总结

  • 在派生类模板中如果需要调用模板基类的方法,需要使用this->,或者明确指出名称。

http://www.ppmy.cn/news/63660.html

相关文章

大语言模型未来趋势以及行业内名字解释

文章目录 名词解释1.大模型的趋势2.大模型的关键技术3. 大模型的应用在不断地应用 名词解释 AIGC:AI生成式内容LLM:大语言模型AGI:通用式生成模型,更高的认知能力的智能系统GPT(Generative Pre-trained Transformer)生成式预训练模型生成式A(I GenerativeArtificialIntelligen…

NEFU-2023-JAVA实验六

题目 分析设计 模拟向货船上装载集装箱。 每个集装箱必须包含ID号以及重量。货船必须包含ID号&#xff0c;名称&#xff0c;以及能承载的总重量&#xff0c;可以包含承载多个集装箱。装载业务逻辑类以及业务逻辑方法&#xff0c;传入指定货船&#xff0c;以及预装载的多个集装箱…

自定义组件中如何注入Spring底层的组件

1.概述 自定义的组件要想使用Spring容器底层的一些组件&#xff0c;比如ApplicationContext&#xff08;IOC容器&#xff09;、底层的BeanFactory等等&#xff0c;那么只需要让自定义组件实现XxxAware接口即可。此时&#xff0c;Spring在创建对象的时候&#xff0c;会调用XxxA…

Netty基础(二)

1.Netty高性能架构设计 1.1.线程模型基本介绍 1>.不同的线程模式,对程序的性能有很大影响,为了搞清Netty线程模式,我们来系统的讲解下各个线程模式,最后看看Netty线程模型有什么优越性; 2>.目前存在的线程模型有: ①.传统阻塞I/O服务模型; ②.Reactor(反应器)模式; 3…

Android 套壳本地html 生成apk

参考了:https://www.jianshu.com/p/ebf7948f3796 首页是前端会给到你html文件 目录基本上是这样的 image.png 步骤1: 创建assets目录 用户安卓studio 新合建工程就不写了 &#xff0c;下面的图是如何创建assets资源目录&#xff1a; image.png image.png 步骤2&#xff1a;拷贝…

【华为OD机试真题 Python】简单的解压缩算法 (100%通过)

前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:nansun0903@163.com;备注:CSDN。 题目描述 现需要实现…

使用 Vert.x 异步发送HTTP长阻塞请求来提高并发响应

假设我们开发了一个必须与其他HTTP服务来交互的服务。不幸的是&#xff0c;这些HTTP服务速度慢且是阻塞的。 它可能是一个非常慢的遗留HTTP服务或我们必须使用的一些阻塞 API。无论如何&#xff0c;我们无法控制它。在这里&#xff0c;我们将调用两个HTTP API。其中一个将阻塞…

8.最长公共子序列问题

title: 8.最长公共子序列问题 date: 2023-05-02 15:52:40 categories: 大学课程内容大二下算法分析基础 8.最长公共子序列问题 【问题描述】 若给定序列X{x1,x2,…,xm}&#xff0c;则另一序列Z{z1,z2,…,zk}&#xff0c;是X的子序列是指存在一个严格递增下标序列{i1,i2,…,i…