高效C++:模板和泛型编程
2024-09-07 19:01:22
模板和泛型编程的关注重点在编译期,所有的行为都在编译期确定,因此其规则和玩法也有自己特殊的一套,和其他模块不通用。
了解隐式接口和编译期多态
元编程------编译器多态,决定哪个重载函数被调用
class的特点:
显示接口
运行期多态
template的特点:
隐式接口
编译器多态,模板的具现和函数的重载
了解typename的双重含义
声明template参数时,前缀关键字class和typename可以互换
使用typename关键字声明嵌套从属类型名称,但不可以出现在基类列表和初始化里列表中
嵌套从属名称
template<typename C>
void Print2Nd(const C& container)
{
...
typename C::const_iterator iter(container.begin()) //确认是类型不是名称
...
} //C::const_iterato 从属嵌套类型(名称中依赖于template类型参数)
学习处理模板化基类内的名称
在Derived class template中调用base class template的函数时,直接调用编译不过,可以使用如下方法:
this->xxx (建议)
basename::xxx
using basename::xxx
class CompanyA{
public:
CompanyA(){} void Send()
{
cout<<"CompanyA::Send()"<<endl;
}
}; class CompanyB{
public:
CompanyB(){} void Send()
{
cout<<"CompanyB::Send()"<<endl;
}
}; template<typename Company>
class Sender{
public:
Sender(){} void SendMsg()
{
Company c;
c.Send();
}
}; template<typename Company>
class LogSender: public Sender<Company>
{
public:
using Sender<Company>::SendMsg; void LogSendMsg()
{
cout<<"LogSender::LogSendMsg() before"<<endl; SendMsg(); //单独使用错误,配合using使用ok
this->SendMsg(); //OK
Sender<Company>::SendMsg(); //OK cout<<"LogSender::LogSendMsg() after"<<endl;
} };
将与参数无关的代码抽取template
不要将函数参数提取为template,这样导致代码冗余
运用成员函数模板接受所有兼容类型
使用模板成员函数生成可接受和兼容所有类型的函数,包括构造函数
template<typename U>
class A
{
public:
template<typename T>
A(A<T>& other)
{
...
}
};
如果将构造函数声明为模板函数,为了阻止编译器生成默认的构造函数,你必须明确声明一个非模板的构造函数
需要类型转换时请为模板定义非成员函数
template在推倒虑隐式转换
对比“定义no-member函数进行类型转换”这一条规则
template<typename T>
const Rational<T> doMutliply(const Rational<T>& lhs, const Rational<T>& rhs)
{
...
} template<typename T>
class Rational
{
public:
...
//声明为friend函数的目的是tempalte推倒,保证编译通过,根本目的是提供一个使用是所有类型的乘法
frined const Rational<T>operator*(const Rational<T>& lhs, const Rational<T>& rhs)
{
return doMutliply(lhs, rhs);
}
}
请使用traits classes表现类型信息
需要了解STL编程,可以参考《STL源码剖析》一书
运用到模板、元编程等知识
了解template元编程
元编程将运行期的工程提前到编译期,错误的发现更早,效率更高
最新文章
- 《C#开发常用免费WebServices集合》
- PS技巧:如何优雅的抠公章?
- tar压缩
- 洛谷 1016 / codevs 1046 旅行家的预算
- 几个Unicode新知识:扩展ANSI有很多种(256个字符),Unicode表示ANSI字符时高字节为0,Unicode不包括古代字符
- CSS样式表其它知识点
- CSS3 实现六边形Div图片展示效果
- c# 强制退出程序
- 为什么要在onNewIntent的时候要显示的去调用setIntent
- javascript编程解决黑化的牛牛问题
- python爬虫xpath
- C++ STL 学习
- 解决 对路径bin\roslyn..的访问被拒绝
- 【转载】Redis Sentinel服务配置
- Hadoop-2.4.0中HDFS文件块大小默认为128M
- 使用gogs和glide来轻松拉取golang第三方库
- HTML5笔记学习(canvas)
- HttpServletResponse和HttpServletRequest详解.RP
- 初学struts2-入门案列
- MySQL 分库、分表