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的讨论。
最新文章
- SQL Server中In-Flight日志究竟是多少
- Uvaoj10054 - The Necklace
- oracle linux 启动
- Stronger (What Doesn't Kill You)
- 使用Ajax与服务器端通信
- 下载安装APK
- [POJ1969]Count on Canton
- ab ApacheBench web测试工具
- 【BZOJ1031】[JSOI2007]字符加密Cipher 后缀数组
- Candy----HDU4465----数学题
- PHP CI框架最近学到的内容
- 【小错误】WPF代码报错:未将对象引用设置到对象的实例。
- javascript中字符串的方法
- visual studio的包含目录配置问题
- WebRequest/HttpWebRequest/HttpRequest/WebClient/HttpClient的区别
- 已知(x,y,z,yaw,pitch,roll)如何得到4*4的转换矩阵?
- php 删除二维数组中某个key值
- NSOperation的使用细节 [3]
- 【贪心算法】POJ-2393 简单贪心水题
- RAII
热门文章
- stat 命令家族(3)- 详解 mpstat
- IT技术人,“三十而已”
- 还不会springboot,阿里p8大牛一份385页pdf直接甩在脸上,给我啃
- unity探索者之微信支付,非第三方插件
- css3新属性position: sticky 一分钟实现 导航栏悬停功能
- UML活动图(二)
- os.path获取当前路径及父路径
- springboot文件上传(可单文件/可多文件)
- idea创建web项目,不能自动导入tomcat包,导致调用request的方法时,无法正常调用
- Pytorch原生AMP支持使用方法(1.6版本)