关于《C++ Templates》
最近买了《C++ Templates》来看,书最开始部分阐述了关于此书的一些编程风格。本人感觉非常好,有些地方之前一直容易搞混,这里却讲述的很清楚。例如:
关于下面几种风格的代码:
void foo(const int &x);
void foo(const int& x);
void foo(int const &x);
void foo(int const& x);
对于上面四种用法,差别虽然不是很大,但是我们更倾向于使用int const,而不是const int。
主要原因:1、关于“恒定不变部分”指的是const限定符前面的部分。
记住这句话,相信诸如此类:int* const book_mark; 和 int const* book_mark; const int* book_mark; 的含义就不会搞错了。
2、使用模板时一个很常用的语法替换原则。例如:
typedef char* CHARS;
typedef CHARS const CPTR; //指向char类型的常量指针,即指针不能改变
当我们用CHARS进行替换后,第2个声明的含义是不变的:
typedef char* const CPTR;
然而,如果我们把const放在它所限定的类型的前面,那么这个原则就不再适用了。考虑如下:
typedef char* CHARS;
typedef const CHARS CPTR; //指向char类型的常量指针,即指针不能改变
如果我们替换CHARS后,第2个声明将导致不同的含义:
typedef const char* CPTR; //指向常量char类型的指针
另外,对于本书的的前两章,下面列了几点重要的结论:
- 模板在编译期间被编译了两次,分别发生在:
1、实例化之前,先检查模板代码之前,查看语法是否正确;在这里会发现错误的语法,如遗漏分号等。
2、在实例化期间,检查模板代码,查看时候所有的调用都有效。在这里会发现无效的调用,如该实例化类型不支持某些函数的调用等。
- 实参演绎时,不允许进行自动类型转换;每个T都必须正确地匹配。如:
template<typename T>
inline T const& max(T const& a, T const& b); max(, ); //OK:两个实参的类型都是int
max(, 4.2) //ERROR:第一个T是int,而第2个T是double
对于上面的错误,有三种方法可以解决:
1、对实参进行强制类型转换,使它们可以互相匹配:
max( static_cast<double>(), 4.2) //OK
2、显式指定(或者限定)T的类型:
max<double>(, 4.2) //OK
3、指定两个参数可以具有不同的类型。
下面从书中摘取了两个例子,代码比较简单,如下所示:
1、函数模板重载的例子。
/**********************************************************
* @filename: C++ templates example: function overloading
* @author: JackyLiu
* @data: 2013.6.25
***********************************************************/ #include <iostream>
#include <cstring>
#include <string> //求两个任意类型值的最大值/////////////////////////////
template <typename T>
inline T const& max(T const& a, T const& b)
{
return a < b ? b : a;
} //求两个指针所指向值的最大值///////////////////////////
template<typename T>
inline T const& max(T* const& a, T* const& b)
{
return *a < *b ? *b : *a;
} //求两个C字符串的最大者////////////////////////////////
inline char const* const& max(char const* const& a,
char const* const& b)
{
return std::strcmp(a,b) < ? b : a;
} int main(int argc, char *argv[])
{
int a = ;
int b = ;
std::cout<< ::max(a, b)<< std::endl; //max()求两个int值的最大值 std::string s = "hey";
std::string t = "you";
std::cout<< ::max(s,t)<< std::endl; //max()求两个std::string类型的最大值 int *p1 = &b;
int *p2 = &a;
std::cout<< ::max(p1,p2)<< std::endl; //max()求两个指针所指向值得最大者 char const* s1 = "David";
char const* s2 = "Nico";
std::cout<< ::max(s1, s2)<< std::endl; //max()求两个c字符串的最大值 int i;
std::cin>> i;
}
2、类模板的例子:
stack3.hpp
#include <vector>
#include <stdexcept> /**
* 缺省模板实参
*/
template<typename T, typename CONT = std::vector<T> >
class Stack
{
private:
CONT elems;
public:
void push(T const&);
void pop();
T top() const;
bool empty() const
{
return elems.empty();
}
}; template<typename T, typename CONT>
void Stack<T, CONT>::push(T const& elem)
{
elems.push_back(elem);
} template<typename T, typename CONT>
void Stack<T, CONT>::pop()
{
if(elems.empty())
throw std::out_of_range("Stack<>::pop(): empty stack");
elems.pop_back();
} template<typename T, typename CONT>
T Stack<T, CONT>::top() const
{
if(elems.empty())
throw std::out_of_range("Stack<>::pop(): empty stack");
return elems.back();
}
main.cpp
/*******************************************************************
* @filename: the implementation of the class template of stack
* @author: JackyLiu
* @date: 2013.6.25
********************************************************************/ #include <iostream>
#include <deque>
#include <string>
#include <cstdlib>
//#include "stack1.hpp"
#include "stack3.hpp" int main(int argc, char *argv[])
{
/*********************************************************************
try
{
Stack<int> intStack; //元素类型为int的栈
Stack<std::string> stringStack; //元素类型为字符串的栈 //使用int栈
intStack.push(7);
std::cout << intStack.top() << std::endl; //使用string栈
stringStack.push("hello");
std::cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch(std::exception const& ex)
{
std::cerr << "Exception: " << ex.what() << std::endl; int i;
std::cin >> i; return EXIT_FAILURE; //程序退出,且带有ERROR标记
}
*/ try
{
//int栈
Stack<int> intStack; //double栈,它使用std::deque来管理元素
Stack<double, std::deque<double> > dblStack; //使用int栈
intStack.push();
std::cout << intStack.top() << std::endl;
intStack.pop(); //使用double栈
dblStack.push(42.42);
std::cout << dblStack.top() << std::endl;
dblStack.pop();
dblStack.pop();
}
catch(std::exception const& ex)
{
std::cerr << "Exception: " << ex.what() << std::endl; int i;
std::cin >> i; return EXIT_FAILURE; //退出程序,且有ERROR标记
}
}
关于《C++ Templates》的更多相关文章
- 关于<meta NAME="keywords" CONTENT="">
昨天终于以实习身份入职一家小创业公司,今天让我多看看别人的网页怎么写的,发现了一个以前都没关注过的东西. <meta name="keywords" content=&quo ...
- 转 :meta name的含义:<META http-equiv=Content-Type content="text/html; charset=gb2312">
meta是什么?meta其实是html语言head区的一个辅助性标签.在几乎所有的网页里,我们都可以看到类似下面这段html代码:<META http-equiv=Content-Type co ...
- HTML <meta> 标签 遇到<meta http-equiv="refresh" content="0; url=">详解
页面定期刷新,如果加url的,则会重新定向到指定的网页,content后面跟的是时间(单位秒),把这句话加到指定网页的<head></head>里一般也用在实时性很强的应用中, ...
- 转 【<meta name="description" content=">】作用讲解
今天在看别人写的网站代码,发现类似<meta name="Keywords" content="" >.<meta name="De ...
- <head>中<meta name="viewport" content="width=device-width,initical-scale=1"的作用>
<meta name="viewport" content="width=device-width,initical-scale=1"的作用> co ...
- 关于<meta http-equiv="X-UA-Compatible" content="IE=edge" />问题
我在做网页过程中都是在火狐浏览器下进行的,可是有一次我在IE浏览器下打开时却发现我设置的style.css中的大部分样式都失效率了,这个问题足足困扰了我两天,终于在百度的帮助下找到了答案,原来在网页的 ...
- 优先使用最新版本的IE 和 Chrome 内核 1 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
兼容模式 优先使用最新版本的IE 和 Chrome 内核 1 <meta http-equiv="X-UA-Compatible" content="IE=edge ...
- 论meta name= viewport content= width=device-width initial-scale=1 minimum-scale=1 maximum-scale=1的作用
一.先明白几个概念 phys.width: device-width: 一般我们所指的宽度width即为phys.width,而device-width又称为css-width. 其中我们可以获取ph ...
- meta name="viewport" content="width=device-width,initial-scale=1.0" 解释
<meta name="viewport" content="width=device-width,initial-scale=1.0"> c ...
- <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 的说明
X-UA-Compatible是针对ie8新加的一个设置,对于ie8之外的浏览器是不识别的,这个区别与 content="IE=7"在无论页面是否包含<!DOCTYPE> ...
随机推荐
- python中的zip
>>> a = zip([1,2,3],[34,35,36]) >>> print(a) <zip object at 0x0394D0F8> > ...
- Hadoop生态圈-hbase介绍-伪分布式安装
Hadoop生态圈-hbase介绍-伪分布式安装 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HBase简介 HBase是一个分布式的,持久的,强一致性的存储系统,具有近似最 ...
- UITextView默认文字提示
在UITextField中自带placeholder属性,可以用于提示输入框信息.但是UITextView并不具备此功能介绍两种方法来实现:第一种:初始化UITextView//首先定义UITextV ...
- tomcat修改java不重启
修改tomcat server.xml 找到项目的Context配置 <Context docBase="项目名" path="/项目路径" relo ...
- shell的父子进程
2017年1月11日, 星期三 shell的父子进程 启动/执行方式: 当前shell: #!/bin/bash 必须行首 ...
- SpringCloud(六) Hystrix入门
前提 一个可用的Eureka注册中心(文中以之前博客中双节点注册中心,不重要) 一个连接到这个注册中心的服务提供者 快速入门 项目搭建 搭建一个新maven项目,artifactid为Ribbon-c ...
- 知名网站内部资料:WEB页面内容优化管理与性能技巧
回想一下,以前我们不得不花费大量时间去优化页面内容(图片.CSS等等),如今用户有更快速的互联网链接,我们似乎能够使用更大的图像或更大的闪 存文件,里面包含的有视频或者图片.然而,随着移动开发的兴起, ...
- java学习第01天(程序开发体验)
1.基本写法 class Demo{ public static void main(String[] args){ System.out.print("Hello World") ...
- 《C语言程序设计基础I》秋季学习总结
希望下学期比这学期轻松,学习能力上升,只是越发丰富. 一步一步的走踏实了
- caffe的特殊层
每次写博客都带有一定的目的,在我看来这是一个记录的过程,所以尽量按照循序渐进的顺序逐步写,前面介绍的CNN层应该是非常常用的,这篇博客介绍一下某些特殊的layer,但是由于特殊的layer都带有一定的 ...