zoukankan      html  css  js  c++  java
  • 关于《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(4, 7);    //OK:两个实参的类型都是int
    max(4, 4.2)   //ERROR:第一个T是int,而第2个T是double

    对于上面的错误,有三种方法可以解决:

    1、对实参进行强制类型转换,使它们可以互相匹配:

    max( static_cast<double>(4), 4.2)   //OK

    2、显式指定(或者限定)T的类型:

    max<double>(4, 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) < 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;
    }

    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(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标记
        }
    }
    当你心中只有一个目标时,全世界都会给你让路!Read more! Write more! Practise more! 新浪微博:liu_军
  • 相关阅读:
    PointToPointNetDevice doesn't support TapBridgeHelper
    NS3系列—10———NS3 NodeContainer
    NS3系列—9———NS3 IP首部校验和
    NS3系列—8———NS3编译运行
    【习题 7-6 UVA
    【Good Bye 2017 C】 New Year and Curling
    【Good Bye 2017 B】 New Year and Buggy Bot
    【Good Bye 2017 A】New Year and Counting Cards
    【Educational Codeforces Round 35 D】Inversion Counting
    【Educational Codeforces Round 35 C】Two Cakes
  • 原文地址:https://www.cnblogs.com/liu-jun/p/3157389.html
Copyright © 2011-2022 走看看