effective c++条款总结(5)
2021/11/21 20:13:36
本文主要是介绍effective c++条款总结(5),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
- 声明template参数是,template< class >和template< typename >是等价的。
但有例外:
template<typename C> // const C& c 不需要加typename void f(const C& c){ // 嵌套从属类型名称,我们需要放置关键字typename // 为了告诉c++编译器C::const_iterator是个类型,缺省的话会被定为为非类型 typename C::const_iterator iter(c.begin()); // 太长的话也可以这么写 typedef typename C::const_iterator Iter; Iter iter(c.begin()); ... }
- 模板类名称使用,模板全特化与偏特化
class Ta{ public: void show(const std::string& msg); ... }; class Tb{ public: void show(const std::string& msg); ... }; class Tc{ public: //没有show()函数 ... }; template<typename T> class MsgShow{ public: void doShow(const std::string& msg){ T t; t.show(msg); } }; //全特化版 template<> class MsgShow<Tc>{ public: ... }; template<typename T> class MsgShowMore : public MsgShow<T>{ public: void doShowMore(const std::string& msg){ doShow(msg); // 无法通过编译,因为此时编译器不知道T是个template参数,不知道是啥东西 } } //为了通过编译,我们要让编译器不进入模板基类观察行为 //1. template<typename T> class MsgShowMore : public MsgShow<T>{ public: void doShowMore(const std::string& msg){ this->doShow(msg); //通过编译 } } //2. template<typename T> class MsgShowMore : public MsgShow<T>{ public: using MsgShow<T>::doShow; void doShowMore(const std::string& msg){ doShow(msg); //通过编译 } } //3. template<typename T> class MsgShowMore : public MsgShow<T>{ public: void doShowMore(const std::string& msg){ MsgShow<T>::doShow(msg); //通过编译 } } //特化版本没有doShow() MsgShowMore<Tc> cmsg; std::string msg; ... cmsg.doShowMore(msa); //错误,因为Tc中没有doShow()函数
模板类与全特化:
//注意:无论是全特化还是偏特化,都必须有一个主模板 //调用优先级:全特化类>偏特化类>主版本模板类 // 主模板 // 模板函数 template<typename T, class C> bool f(T t, C c){ return (t > c); } // 模板类 template<typename T, class C> class F{ public: bool f(T t, C c){ return (t > c); } }; // 全特化 template<> bool f(int t, double c){ return (t > c); } template<> class F{ public: bool f(int t, double c){ return (t > c); } }; //偏特化 template<typename T> bool f(T t, double c){ return (t > c); } template<class C> class F{ public: bool f(int t, C c){ return (t > c); } }; //调用函数 int a = 1; double b = 2.0; f<int, double>(a, b); F<int, double>::f(a, b);
- 因非类型模板参数而造成的代码膨胀,可以用函数参数或类成员变量替换模板参数;因类型参数造成的代码膨胀,可以让带有完全相同二进制表述的具体类型共享实现码。
template<typename T, std::size_t s> class D { public: void area(s){ ... } }; // 当我们调用的时候,造成代码膨胀 D<double, 5> d1; D<double, 10> d2; d1.area(); d2.area(); //方法1. 共享同个基类,所以能共享同个show template<typename T> class B{ protected: void area(std::size_t s); }; template<typename T, std::size_t s> class D : private B<T>{ private: using B<T>::show; public: void area(){ this->area(s); //inline } }; // 方法2. 储存一个指针,指向数值所在内存 template<typename T> class B{ protected: B(std::size_t s, T* t) : size(s), data(t){} void setData(T* t) { data = t;} void area(){ ... } private: std::size_t size; T* data; }; template<typename T, std::size_t s> class D : private B<T>{ public: D() : B<T> (s, data) private: T data[s*s]; }; // 方法3. 将数据放进heap,通过new来分配内存 template<typename T> class B{ protected: B(std::size_t s, T* t) : size(s), data(t){} void setData(T* t) { data = t;} void area(){ ... } private: std::size_t size; T* data; }; template<typename T, std::size_t s> class D : private B<T>{ public: D() : B<T> (s, 0), data (new T[n*n]){ this->setData(data.get()); } private: boost::scoped_array<T> data; };
这篇关于effective c++条款总结(5)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升