返回完整目录

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)的更多相关文章

  1. 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 ...

  2. 对C++ templates类模板的几点补充(Traits类模板特化)

    前一篇文章<浅谈C++ templates 函数模板.类模板以及非类型模板参数>简单的介绍了什么是函数模板(这个最简单),类模板以及非类型模板参数.本文对类模板再做几点补充. 文章目录1. ...

  3. 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++ ...

  4. C++STL - 类模板

    类的成员变量,成员函数,成员类型,以及基类中如果包含参数化的类型,那么该类就是一个类模板   1.定义 template<typename 类型形参1, typename 类型形参2,...&g ...

  5. Xcode7建立自己的自定义工程和类模板

    首先进入系统模板的目录 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library ...

  6. Xcode6中如何使用自定义的类模板

    说到IOS类的模板,有些人感觉很陌生,但是只要有开发过IOS程序的人,其实都用过类的模板,只不过是用的系统自带的类的模板. 例如创建一个ClassTemplateVC继承于UIViewControll ...

  7. 用auto_ptr类模板帮助动态内存管理

    动态内存使用最多的是在C++应用程序的代码中.有过编程经验的程序员虽然都知道new操作符的使用一定要与delete匹配,在某些场合仍然可能有内存溢出.当异常被掷出时,程序的正常控制流程被改变,因此导致 ...

  8. XCode5添加新建类模板(Cocos2dx Template Class for Scene or Layer)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=505 因为常用cocos2dx开 ...

  9. C++—模板(2)类模板与其特化

    我们以顺序表为例来说明,普通顺序表的定义如下: typedef int DataType; //typedef char DataType; class SeqList { private : Dat ...

随机推荐

  1. [源码解析] 当 Java Stream 遇见 Flink

    [源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...

  2. 火题大战Vol.1 A.

    火题大战Vol.1 A. 题目描述 给定两个数\(x\),\(y\),比较\(x^y\) 与\(y!\)的大小. 输入格式 第一行一个整数\(T\)表示数据组数. 接下来\(T\)行,每行两个整数\( ...

  3. JDK1.8源码学习-String

    JDK1.8源码学习-String 目录 一.String简介 String类是Java中最常用的类之一,所有字符串的字面量都是String类的实例,字符串是常量,在定义之后不能被改变. 二.定义 p ...

  4. FIRST集合、FOLLOW集合及LL(1)文法求法

    FIRST集合 定义 可从α推导得到的串的首符号的集合,其中α是任意的文法符号串. 规则 计算文法符号 X 的 FIRST(X),不断运用以下规则直到没有新终结符号或 ε可以被加入为止 : (1)如果 ...

  5. CCF-202006-1线性分类器

    1 def judga(lis1,z): #判断列表lis1中点是否都在线z的一侧 s=0 for i in lis1: if z[0]+i[0]*z[1]+i[1]*z[2]>0: s+=1 ...

  6. HM16.0之帧间预测——xCheckRDCostInter()函数

    参考:https://blog.csdn.net/nb_vol_1/article/category/6179825/1? 1.源代码: #if AMP_MRG Void TEncCu::xCheck ...

  7. you-get 下载B站上的视频

    安装you-get pip install you-get 安装好后,我们可以查看一下you-get的参数 you-get -h 视频下载 单个视频下载 CMD下载 you-get -o /data/ ...

  8. Java多线程同步_synchronized

    1.synchronized是什么?synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种:1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起 ...

  9. 图数据库对比:Neo4j vs Nebula Graph vs HugeGraph

    本文系腾讯云安全团队李航宇.邓昶博撰写 图数据库在挖掘黑灰团伙以及建立安全知识图谱等安全领域有着天然的优势.为了能更好的服务业务,选择一款高效并且贴合业务发展的图数据库就变得尤为关键.本文挑选了几款业 ...

  10. jQuery源码分析系列(三)Sizzle选择器引擎-下

    选择函数:select() 看到select()函数,if(match.length === 1){}存在的意义是尽量简化执行步骤,避免compile()函数的调用. 简化操作同样根据tokenize ...