最近买了《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》的更多相关文章

  1. 关于<meta NAME="keywords" CONTENT="">

    昨天终于以实习身份入职一家小创业公司,今天让我多看看别人的网页怎么写的,发现了一个以前都没关注过的东西. <meta name="keywords" content=&quo ...

  2. 转 :meta name的含义:<META http-equiv=Content-Type content="text/html; charset=gb2312">

    meta是什么?meta其实是html语言head区的一个辅助性标签.在几乎所有的网页里,我们都可以看到类似下面这段html代码:<META http-equiv=Content-Type co ...

  3. HTML <meta> 标签 遇到<meta http-equiv="refresh" content="0; url=">详解

    页面定期刷新,如果加url的,则会重新定向到指定的网页,content后面跟的是时间(单位秒),把这句话加到指定网页的<head></head>里一般也用在实时性很强的应用中, ...

  4. 转 【<meta name="description" content=">】作用讲解

    今天在看别人写的网站代码,发现类似<meta name="Keywords" content="" >.<meta name="De ...

  5. <head>中<meta name="viewport" content="width=device-width,initical-scale=1"的作用>

    <meta name="viewport" content="width=device-width,initical-scale=1"的作用> co ...

  6. 关于<meta http-equiv="X-UA-Compatible" content="IE=edge" />问题

    我在做网页过程中都是在火狐浏览器下进行的,可是有一次我在IE浏览器下打开时却发现我设置的style.css中的大部分样式都失效率了,这个问题足足困扰了我两天,终于在百度的帮助下找到了答案,原来在网页的 ...

  7. 优先使用最新版本的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 ...

  8. 论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 ...

  9. meta name="viewport" content="width=device-width,initial-scale=1.0" 解释

     <meta name="viewport" content="width=device-width,initial-scale=1.0">   c ...

  10. <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 的说明

    X-UA-Compatible是针对ie8新加的一个设置,对于ie8之外的浏览器是不识别的,这个区别与 content="IE=7"在无论页面是否包含<!DOCTYPE> ...

随机推荐

  1. Go_15:GoLang中面向对象的三大特性

    有过 JAVA 语言学习经历的朋友都知道,面向对象主要包括了三个基本特征:封装.继承和多态.封装,就是指运行的数据和函数绑定在一起,JAVA 中主要是通过 super 指针来完成的:继承,就是指 cl ...

  2. java基础-BigDecimal类常用方法介绍

    java基础-BigDecimal类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.BigDecimal类概述 我们知道浮点数的计算结果是未知的.原因是计算机二进制 ...

  3. [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

    转载自:https://segmentfault.com/a/1190000006435886 解决办法:添加package.config.js配置文件中,添加本文章的红色部分代码 import vu ...

  4. Shell记录-Shell脚本基础(二)

    Shell 基本运算符 算术运算符: 运算符 描述 例子 + Addition - Adds values on either side of the operator `expr $a + $b` ...

  5. 调用weka模拟实现 “主动学习“ 算法

    主动学习: 主动学习的过程:需要分类器与标记专家进行交互.一个典型的过程: (1)基于少量已标记样本构建模型 (2)从未标记样本中选出信息量最大的样本,交给专家进行标记 (3)将这些样本与之前样本进行 ...

  6. c# dev GridControl多选当前行显示样式问题

    由于Dev GridControl在支持多选的时候,如果如果焦点行单独加了样式,Appearance-->FocusedRow  &  HideSelectionRow 这个时候,鼠标焦 ...

  7. soj1010. Zipper

    1010. Zipper Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Given three strings, yo ...

  8. HDU 4548 美素数 在线打表加数状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4548 解题报告:一开始本想先打个素数表,然后每次输入L 跟R 的时候都进行暴力判断,但这题测试数据太多 ...

  9. 训练赛第二场G题 ZOJ 2343

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2343 解题报告:首先我假设最后的正确的结果是a[1] , a[2 ...

  10. [转] A*寻路算法C++简单实现

    参考文章: http://www.policyalmanac.org/games/aStarTutorial.htm   这是英文原文<A*入门>,最经典的讲解,有demo演示 http: ...