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

这篇具有很好参考价值的文章主要介绍了effective c++ 43-处理模板化基类的名称 笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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文章来源地址https://www.toymoban.com/news/detail-435096.html

总结

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

到了这里,关于effective c++ 43-处理模板化基类的名称 笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3实现组件级基类的几种方法

    Vue3的组件有三种代码组织方式 纯Option API (不含setup) option API + setup 纯 setup (即composition API) 对于这三种形式,设置基类的方法也略有不同。 vue3提供了 mixins和extends,但是尝试之后发现这两种方法只支持纯OptionAPI,设置的data会被识别,但是设置的setup里return 的 reactive,完

    2024年02月01日
    浏览(47)
  • 【Unity之IMGUI】—位置信息类和控件基类的封装

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : 缺点1:无法在编译过程进行可视化调整 缺点2:无法分辨率自适应 作用:让控件根据调整对齐 最终代码 特点: 类是抽象类:原因基类

    2024年02月12日
    浏览(25)
  • 基于C/C++将派生类赋值给基类的详细讲解

    目录 将派生类对象赋值给基类对象 将派生类指针赋值给基类指针

    2024年02月08日
    浏览(47)
  • 【Unity之IMGUI脚本封装】—位置信息类和控件基类的封装

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : 缺点1:无法在编译过程进行可视化调整 缺点2:无法分辨率自适应 作用:让控件根据调整对齐 最终代码 特点: 类是抽象类:原因基类

    2024年02月17日
    浏览(34)
  • [Lua] 实现所有类的基类Object、模拟单继承OO、实现抽象工厂

    Lua 没有严格的 oo(Object-Oriented)定义,可以利用元表特性来实现 先定义所有类的基类,即 Object 类。代码顺序从上到下,自成一体。完整代码 定义一个空表 Object , __index 指向其自身(继承将直接使用该表作为对象的元表) new 定义构造对象时的初始化行为,相当于 构造器

    2024年02月11日
    浏览(30)
  • C++虚基类

    如果一个派生类是从多个基类派生出来的,而这些基类又有一个共同的基类,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性。 比如有以下结构 以下程序会报错,因为a具有二义性。 能够看到a被初始化了两次,我们希望a只被再第一次初始化以后就不再

    2024年02月08日
    浏览(37)
  • C++ | 继承(基类,父类,超类),(派生类,子类)

    文章参考:https://blog.csdn.net/war1111886/article/details/8609957 一 .继承中的访问权限关系 1.基类,父类,超类是指被继承的类,派生类,子类是指继承于基类的类.  2.在C++中使用: 冒号表示继承,如class A : public B;表示派生类A从基类B继承而来 3.派生类包含基类的所有

    2024年02月15日
    浏览(30)
  • OpenCV数字图像处理实战二:模板匹配(C++)

    (1)首先需要一个模板图像 T(子图像)和一个待检测的图像(源图像 S) (2)在待检测图像从左到右,从上到下计算模板图像与重叠子图像的匹配度,匹配度越高,两者相同的可能性越大。 3.1 单模板匹配 注意:result的长宽正好是(原图-模板图)的长宽,result图中白亮程

    2024年02月15日
    浏览(34)
  • C++的基类和派生类构造函数

    基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数,类的构造函数不能被继承。构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。

    2024年02月10日
    浏览(41)
  • Matlab论文插图绘制模板第43期—直方图(histogram)

    在之前的文章中,分享过很多 柱状图的Matlab绘制模板 : 这一次,来分享一种比较特殊的柱状图: 统计直方图 。 先来看一下 成品效果 : 特别提示 :Matlab论文插图绘制模板系列, 旨在降低大家使用Matlab进行科研绘图的门槛 ,只需按照模板格式添加相应内容,即可得到满足

    2024年02月15日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包