C++ Templates (2.3 类模板的局部使用 Partial Usage of Class Templates)
2.3 类模板的局部使用 Partial Usage of Class Templates
类模板通常在它实例化的模板实参上进行多种操作(包括构造和析构),这给人一种印象:模板实参必须提供所有类模板的所有成员函数的所有操作。但是事实并非如此:模板实参仅需提供必要的操作而非可能需要的操作。
比如说,如果类Stack<>提供一个成员函数printOn()用于打印整个stack的内容,并对每个元素调用operator<<:
template <typename T>
class Stack
{
...
void printOn(std::ostream& strm) const
{
for(T const& elem: elems)
{
strm << elem << ' '; //每个元素调用<<
}
}
}
但这依然可以使用没有定义operator<<的类作为该类模板的模板实参:
Stack<std::pair<int,int>> ps; //注意: std::pair<>没有定义operator<<
ps.push({4, 5}); //OK
ps.push({6,7}); //OK
std::cout << ps.top().first << '\n'; //OK
std::cout << ps.top().second << '\n'; //OK
只有当调用这样的stack的printOn()方法时,该代码才会生成错误,因为它不能实例化对该特殊类型的operator<<的调用:
ps.printOn(std::cout); //ERROR: 元素类型不支持operator<<
2.3.1 Concepts
这引发了一个问题,如何知道哪些是模板实例化所需要的操作?术语概念(Concept)用于指示约束条件的集合,并在模板库中重复使用。比如,C++标准库依赖于随机访问迭代器(random access iterator)和默认构造(default constructible)。
当前(C++17),concepts只能或多或少地在文档中进行表述(比如代码注释)。这可能是个重要的问题,因为未遵循约束条件的错误可能引起恶心的错误消息(详见第9.4节)。
许多年来,有许多方法和试验来支持concepts的定义和验证,将其作为语言特性。然而,截止C++17还没有标准化的方法。
自从C++11以后,至少可以通过使用static_assert关键字和预定义的类型特性来检查基本的约束条件,比如:
template <typename T>
class C
{
static_assert(std::is_default_constructible<T>::value, "Class C requires default-constructible elements");
...
}
没有该断言,如果需要默认构造函数,编译依然会失败。然而,该错误信息可能包含整个模板实例化的历史,从开始实例化到真实的模板定义(即错误检测到的地方,详见9.4节)。
然而,更多复杂的代码需要检查,比如,类型T的对象提供一种特殊的成员函数或者他们可以使用操作<进行比较。详见19.6.3节的一个详细的代码例程。
参考附件E关于更多的有关C++ Concept的讨论。
C++ Templates (2.3 类模板的局部使用 Partial Usage of Class Templates)的更多相关文章
- C++ Templates (2.1 类模板Stack的实现 Implementation of Class Template Stack)
返回完整目录 目录 2.1 类模板Stack的实现 Implementation of Class Template Stack 2.1.1 声明类模板 Declaration of Class Te ...
- 对C++ templates类模板的几点补充(Traits类模板特化)
前一篇文章<浅谈C++ templates 函数模板.类模板以及非类型模板参数>简单的介绍了什么是函数模板(这个最简单),类模板以及非类型模板参数.本文对类模板再做几点补充. 文章目录1. ...
- C++ Templates (2.2 使用Stack类模板 Use of Class Template Stack )
返回完整目录 目录 2.2 使用Stack类模板 Use of Class Template Stack 2.2 使用Stack类模板 Use of Class Template Stack 在C++ ...
- C++STL - 类模板
类的成员变量,成员函数,成员类型,以及基类中如果包含参数化的类型,那么该类就是一个类模板 1.定义 template<typename 类型形参1, typename 类型形参2,...&g ...
- Xcode7建立自己的自定义工程和类模板
首先进入系统模板的目录 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library ...
- Xcode6中如何使用自定义的类模板
说到IOS类的模板,有些人感觉很陌生,但是只要有开发过IOS程序的人,其实都用过类的模板,只不过是用的系统自带的类的模板. 例如创建一个ClassTemplateVC继承于UIViewControll ...
- 用auto_ptr类模板帮助动态内存管理
动态内存使用最多的是在C++应用程序的代码中.有过编程经验的程序员虽然都知道new操作符的使用一定要与delete匹配,在某些场合仍然可能有内存溢出.当异常被掷出时,程序的正常控制流程被改变,因此导致 ...
- XCode5添加新建类模板(Cocos2dx Template Class for Scene or Layer)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=505 因为常用cocos2dx开 ...
- C++—模板(2)类模板与其特化
我们以顺序表为例来说明,普通顺序表的定义如下: typedef int DataType; //typedef char DataType; class SeqList { private : Dat ...
随机推荐
- 解决用anaconda安装scrapy后,在使用scrapy时报错
python版本为3.7 因为用anaconda安装scrapy非常方便,会自动下载所依赖的包, 所以就使用anaconda安装scrapy, 非常舒服,安装很成功 conda install scr ...
- west_wild 靶机
ways:smb枚举+suid提权 1:扫描主机发现IP 老套路:netdiscover 一波 2:nmap扫描,发现开放的 端口很多并且开放是SMB协议 3:对目录扫描,发现没有可以利用的点 4:从 ...
- Golang 简单爬虫实现,爬取小说
为什么要使用Go写爬虫呢? 对于我而言,这仅仅是练习Golang的一种方式. 所以,我没有使用爬虫框架,虽然其很高效. 为什么我要写这篇文章? 将我在写爬虫时找到资料做一个总结,希望对于想使用Gola ...
- 二叉搜索树 [四边形不等式优化区间dp]
二叉搜索树 [四边形不等式优化区间dp] 题目描述 有 \(n\) 个结点,第 \(i\) 个结点的权值为 \(i\) . 你需要对它们进行一些操作并维护一些信息,因此,你需要对它们建立一棵二叉搜索树 ...
- 0x01 基本算法-位运算 a^b
#include<bits/stdc++.h>using namespace std;int power(int a, int b, int p){ int ans = 1%p; ...
- JAVA使用urlrewrite实现伪静态化
什么是伪静态? 伪静态字面理解就是假的静态,说的官方点就是“地址重写,用户得到的全部地址都是经过处理后的URL地址”. 为什么要伪静态呢? 提高安全性,可以有效的避免一些参数名.ID等完全暴露在用户面 ...
- SpringBoot整合Actuator进行健康监控
一.Actuator介绍 SpringBoot自带监控功能Actuator,通过 restful api 请求来监管.审计.收集应用的运行情况,可以帮助实现对程序内部运行情况监控,比如监控状况.Bea ...
- MySQL必知必会》正则表达式
<MySQL必知必会>正则表达式 正则表达式 1.1.关键字 REGEXP 正则表达式的使用需要用到关键字 REGEXP . select prod_name from products ...
- latex三种标准文类book, report, article的章节命令与层次深度
Latex有三种标准文类:book, report, article. 每种文类的章节命令和层次深度如下: 三种标准文类的章节命令与层次深度 层次深度 层次名 book report article ...
- Java数据结构——二叉树的遍历(汇总)
二叉树的遍历分为深度优先遍历(DFS)和广度优先遍历(BFS) DFS遍历主要有: 前序遍历 中序遍历 后序遍历 一.递归实现DFSNode.java: public class Node { pri ...