美文网首页c++ 模版
C++11 模板元编程 - 模板的类型参数

C++11 模板元编程 - 模板的类型参数

作者: MagicBowen | 来源:发表于2016-09-14 09:44 被阅读1468次

    下面是我们熟悉的类模板的例子:一个简单的容器栈,它可以支持不同的类型做元素。

    #include <vector>
    #include <stdexcept>
    
    template<typename T>
    struct Stack
    {
        void push(const T& elem)
        {
            elems.push_back(elem);
        }
    
        T pop()
        {
            if(empty()) throw std::out_of_range("Stack<>::pop: empty!");
    
            auto elem = elems.back();
            elems.pop_back();
            return elem;
        }
    
        bool empty() const
        {
            return elems.empty();
        }
    
    private:
        std::vector<T> elems;
    };
    

    它的用法如下:

    Stack<int> intStack;
    intStack.push(-1);
    intStack.push(2);
    intStack.push(-3);
    std::cout << intStack.pop() << std::endl;
    
    Stack<char> charStack;
    charStack.push('A');
    charStack.push('B');
    std::cout << charStack.pop() << std::endl;
    

    对于模板元编程,我们可以将类模板想象成一个编译期的函数,不同的是它的参数列表放在一对尖括号中。通过template<typename T> struct Stack我们声明了一个编译期的函数,它的名字叫做Stack,它有一个类型形参T。

    标准规定可以用typename或者class关键字指示模板形参是一个类型,不能使用struct。由于模板的类型形参不仅可以被替换为用户自定义类型,也可以被替换为内置类型(int, char, double...),所以使用typename语义上比class更清晰一些。本文统一使用typename。

    如同把具体的实参传递给一个函数,函数就会计算求值一样,当我们把具体的类型当做实参传递给类模板时,类模板会在编译期进行计算,返回一个具体的类型。类模板的传参和函数类似,只不过语法上使用尖括号。

    上例中我们分别将int和char当做实参,传递给类模板Stack。Stack得到实参后变成具体的类型Stack<int>Stack<char>。根据运行期C++的要求,只有具体类型才能产生对象,所以我们分别用Stack<int>Stack<char>生成了两个对象intStackcharStack

    类模板的实现中可以继续使用类模板。上例中Stack的实现中使用了标准库中的类模板std::vector。一旦我们在Stack中用具体类型替换形参T,std::vector<T>也会被传递参数从而变成一个具体类型,使得可以产生elems对象。

    上面虽然我们用编译期函数来类比类模板,但是这时的类模板还远未达到模板元编程的要求,我们继续!


    模板的默认参数

    返回 C++11模板元编程 - 目录

    相关文章

      网友评论

        本文标题:C++11 模板元编程 - 模板的类型参数

        本文链接:https://www.haomeiwen.com/subject/hnrvettx.html