关于《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> ...
随机推荐
- golang 中 sync包的 WaitGroup
golang 中的 sync 包有一个很有用的功能,就是 WaitGroup 先说说 WaitGroup 的用途:它能够一直等到所有的 goroutine 执行完成,并且阻塞主线程的执行,直到所有的 ...
- P4779 【模板】单源最短路径(标准版)
P4779 [模板]单源最短路径(标准版) 求单源最短路, 输出距离 Solution \(nlogn\) 堆优化 \(Djs\) Code #include<iostream> #inc ...
- python---django的模块简便使用
一:登录操作 from django.contrib.auth import authenticate,login,logout #可以用来做登录验证 from django.contrib.auth ...
- Kafka 0.8 Consumer处理逻辑
0.前言 客户端用法: kafka.javaapi.consumer.ConsumerConnector consumer = kafka.consumer.Consumer.createJavaCo ...
- 【c#】腾讯人脸识别api签名
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...
- Mac下MySQL的卸载
先停止所有mysql有关进程. 打开控制台一次复制下列所有内容: sudo rm /usr/local/mysql sudo rm -rf /usr/local/mysql* sudo rm -rf ...
- python核心编程笔记——Chapter8
Chapter8.条件和循环 这一章感觉有用的点并不多,在我眼里就只有迭代器,列表解析和生成器表达式值得研究而已. 8.2.循环,难度不大. #!usr/bin/env python #-*-codi ...
- Javascript的V8引擎研究
1.针对上下文的Snapshot技术 什么是上下文(Contexts)?实际是JS应用程序的运行环境,避免应用程序的修改相互影响,例如一个页面js修改内置对象方法toString,不应该影响到另外页面 ...
- bzoj 1044 [HAOI2008]木棍分割(二分+贪心,DP+优化)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1044 [题意] n根木棍拼到一起,最多可以切m刀,问切成后最大段的最小值及其方案数. ...
- shell作业后台执行的方法
来思考几种场景: 1.某个脚本需要执行时间比较长,无人值守,可能执行过程中因ssh会话超时而中断? 2.某次测试一段代码,需要临时放入后台运行? 3.放入后台运行的脚本,需要在一段时间后重新调到前台? ...