关于《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> ...
随机推荐
- 跨域ajax请求携带cookie
通过withCredentials 方式: getCompanySubject: function () { return axios.get(this.apiUrls.getCompanySubje ...
- NOIP2012 提高组 Day 1
期望得分:100+100+70=270 实际得分:100+50+70=220 T2 没有底 最后剩余时间来不及打高精.思路出现错误 T1 Vigenère 密码 题目描述 16 世纪法国外交家 Bla ...
- jquery radio的操作
radio 按钮组, name=”sex”. <input type="radio" name="sex" value="Male"& ...
- Java入门系列(一)基础概览
序言 Java语言的特点不使用指针而使用引用.
- 29、HashSet简介
Set的特点 Set里面存储的元素不能重复,没有索引,存取顺序不一致. package com.monkey1024.set; import java.util.HashSet; /** * Set的 ...
- 最短路径—Floyd算法
Floyd算法 所有顶点对之间的最短路径问题是:对于给定的有向网络G=(V,E),要对G中任意两个顶点v,w(v不等于w),找出v到w的最短路径.当然我们可以n次执行DIJKSTRA算法,用FLOYD ...
- ubuntu下使用qemu模拟ARM(六)------驱动程序【转】
转自:http://blog.csdn.net/rfidunion/article/details/54709843 驱动程序分为在ubuntu上运行和在ARM开发板上运行两种,我们分别来进行测试 1 ...
- 64_t8
trytond-account-de-skr03-4.0.0-3.fc26.noarch.rpm 12-Feb-2017 13:06 53278 trytond-account-invoice-4.0 ...
- linq和ef关于group by取最大值的两种写法
LINQ: var temp = from p in db.jj_Credentials group p by p.ProfessionID into g select new { g.Key, Ma ...
- 转载:Github项目解析(七)-->防止按钮重复点击
不错的东西,记录下... http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/qq_23547831/article/deta ...