C++模版笔记(1)
2023-06-13 09:13:58 时间
本篇介绍
本篇摘录自<<C++ templates>>,记录其中部分内容。
Variadic Templates
操作可变参数
template <typename T>
void func(T arg) {
std::cout<< arg << std::endl;
}
template <typename T, typename ... Types>
void func(T firstArg, Types... args) {
func(firstArg);
func(args...);
}
使用sizeof...(args)即可获取到变量个数。
在c++ 17上可以按照如下方式操作可变入参:
template <typename... T>
auto sum(T... s) {
return (... + s); // ((s1 +s2) + s3)
}
具体格式如下:
image.png
std::enable_if
利用SFINE性质,也就是只要可以匹配成功,即使某些场景匹配失败也不是错误。
template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
using 在模版中的使用
using 有给类型重命名的作用,也有继承父类所有构造函数的作用,比如:
struct Base {
int val;
Base() { val = 0;}
Base(int m):val(m) {
}
};
struct Derived : public Base {
using Base::Base;
};
通过using 就可以一下子使用到父类的所有构造函数。
也可以通过模版支持获取所有类的操作符重载方法:
class Customer
{
private:
std::string name;
public:
Customer(std::string const& n) : name(n) { }
std::string getName() const { return name; }
};
struct CustomerEq {
bool operator() (Customer const& c1, Customer const& c2) const {
return c1.getName() == c2.getName();
}
};
struct CustomerHash {
std::size_t operator() (Customer const& c) const {
return std::hash<std::string>()(c.getName());
}
};
template<typename... Bases>
struct Overloader : Bases...
{
using Bases::operator()...;
};
using CustomerOP = Overloader<CustomerHash,CustomerEq>;
std::unordered_set<Customer,CustomerOP,CustomerOP> col;
typename
在模版使用过程中,typename 和class 是等同的,不过typename还有一层含义,就是修饰的参数一定是类型。
template<typename T>
class MyClass {
public: ...
void foo() {
typename T::SubType* ptr;
} };
这儿的 T::SubType 是类型。
模版友元
如果希望支持模版不同特化之间可以访问私有数据,那么就可以设置模版特化是友元的。
template <typename T>
class Stack {
template <typename> friend class Stack;
};
变量模版
可以用变量来表示类模版的成员值:
namespace std {
template<typename T> constexpr bool is_const_v = is_const<T>::value;
}
这样通过is_const_v<T> 就可以表示 is_const<T>::value
模版模版参数
如果模版参数中的类型本身也是一个模版,比如还是Stack, Stack<int, std::vector<int>> 可以看到第一个模版参数是int,第二个模版参数还是一个int,这时候就是模版的模版参数了,要声明这种场景,方法如下:
template<typename T,
template<typename Elem> class Cont = std::deque>
在模版里再写一下 template<typename Elem>,就表明第二个参数也是模版。 这时候完整的Stack 如下:
#include <deque>
#include <cassert>
#include <memory>
template<typename T,
template<typename Elem,
typename = std::allocator<Elem>>
class Cont = std::deque>
class Stack {
private:
Cont<T> elems;
public:
void push(T const&);
void pop();
T const& top() const;
bool empty() const {
return elems.empty();
}
// assign stack of elements of type T2 template<typename T2,
template<typename Elem2,
typename = std::allocator<Elem2>
>class Cont2>
Stack<T,Cont>& operator= (Stack<T2,Cont2> const&);
// to get access to private members of any Stack with elements of type T2: template<typename, template<typename, typename>class> friend class Stack;
};
template<typename T, template<typename,typename> class Cont>
void Stack<T,Cont>::push (T const& elem)
{
elems.push_back(elem); // append copy of passed elem
}
template<typename T, template<typename,typename> class Cont>
void Stack<T,Cont>::pop ()
{
assert(!elems.empty());
elems.pop_back();
// remove last element
}
template<typename T, template<typename,typename> class Cont>
T const& Stack<T,Cont>::top () const
{
assert(!elems.empty());
return elems.back(); // return copy of last element
}
template<typename T, template<typename,typename> class Cont>
template<typename T2, template<typename,typename> class Cont2>
Stack<T,Cont>&
Stack<T,Cont>::operator= (Stack<T2,Cont2> const& op2)
{
elems.clear();
elems.insert(elems.begin(),
op2.elems.begin(),
op2.elems.end());
return *this;
// remove existing elements // insert at the beginning
// all elements from op2
}
相关文章
- C++项目职工管理系统笔记-项目代码
- C++系列笔记(二)
- C++系列笔记(五)
- C++系列笔记(七)
- C++系列笔记(八)
- C++系列笔记(十)
- C++系列笔记(十二)
- c++语言截取字符串,详解C++ string常用截取字符串方法
- C++QT常见面试题[通俗易懂]
- C++项目贪吃蛇游戏笔记-C语言版
- C++学习笔记
- 【2022新书】C++软件设计:高质量软件的设计原则和模式
- 《SiamFC++:Towards Robust and Accurate Visual Tracking with Target Estimation Guidelines》论文笔记
- C/C++ 数据结构与算法笔记
- C/C++ 文件与指针操作笔记
- C/C++ Qt 命令行版网络通信
- C++ 20 学习笔记1 --From BiliBili.com
- C++基础——C++面向对象之重载与多态基础总结(函数重载、运算符重载、多态的使用)
- C++面向对象程序设计(谭浩强)第三章 怎样使用类和对象 第一节学习笔记
- C++面向对象程序设计(谭浩强)第三章第二~四节 学习笔记
- c++基础篇之C++ 模板
- sap JCO3.0安装缺少Microsoft Visual C++ 2005 Service Pack 1 Redistributable Package (KB973544)详解编程语言
- C++序列容器存储智能指针详解
- C++ STL move_iterator移动迭代器用法详解
- C++Primer笔记之关联容器的使用详解
- 关于C++中的static关键字的总结
- C++类中的static和const用法实例教程