最近買了《C++ Templates》來看,書最開始部分闡述了關於此書的一些編程風格。本人感受很是好,有些地方以前一直容易搞混,這裏卻講述的很清楚。例如:ios
關於下面幾種風格的代碼:編程
void foo(const int &x); void foo(const int& x); void foo(int const &x); void foo(int const& x);
對於上面四種用法,差異雖然不是很大,可是咱們更傾向於使用int const,而不是const int。函數
主要緣由:一、關於「恆定不變部分」指的是const限定符前面的部分。spa
記住這句話,相信諸如此類:int* const book_mark; 和 int const* book_mark; const int* book_mark; 的含義就不會搞錯了。指針
二、使用模板時一個很經常使用的語法替換原則。例如:code
typedef char* CHARS; typedef CHARS const CPTR; //指向char類型的常量指針,即指針不能改變
當咱們用CHARS進行替換後,第2個聲明的含義是不變的:blog
typedef char* const CPTR;
然而,若是咱們把const放在它所限定的類型的前面,那麼這個原則就再也不適用了。考慮以下:ci
typedef char* CHARS; typedef const CHARS CPTR; //指向char類型的常量指針,即指針不能改變
若是咱們替換CHARS後,第2個聲明將致使不一樣的含義:字符串
typedef const char* CPTR; //指向常量char類型的指針
另外,對於本書的的前兩章,下面列了幾點重要的結論:string
一、實例化以前,先檢查模板代碼以前,查看語法是否正確;在這裏會發現錯誤的語法,如遺漏分號等。
二、在實例化期間,檢查模板代碼,查看時候全部的調用都有效。在這裏會發現無效的調用,如該實例化類型不支持某些函數的調用等。
template<typename T> inline T const& max(T const& a, T const& b); max(4, 7); //OK:兩個實參的類型都是int max(4, 4.2) //ERROR:第一個T是int,而第2個T是double
對於上面的錯誤,有三種方法能夠解決:
一、對實參進行強制類型轉換,使它們能夠互相匹配:
max( static_cast<double>(4), 4.2) //OK
二、顯式指定(或者限定)T的類型:
max<double>(4, 4.2) //OK
三、指定兩個參數能夠具備不一樣的類型。
下面從書中摘取了兩個例子,代碼比較簡單,以下所示:
一、函數模板重載的例子。
/********************************************************** * @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) < 0 ? b : a; } int main(int argc, char *argv[]) { int a = 7; int b = 42; 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; }
二、類模板的例子:
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(7); 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標記 } }