c++ template归纳学习5

简介:

双重模板参数:

我们还是以前几篇中的Stack为例子i:代码如下:

template <typename T, 
          template <typename ELEM> class CONT = std::deque > 
class Stack { 
  private: 
    CONT<T> elems;         // elements 

  public: 
    void push(T const&);   // push element 
    void pop();            // pop element 
    T top() const;         // return top element 
    bool empty() const {   // return whether the stack is empty 
        return elems.empty(); 
    } 
}; 
在这段代码中,我们的第二个模板参数修改为:template <typename ELEM> class CONT

和往常一样,你可以使用class替代typename,但是CONT必须是class。

template <typename T, 
          template <class ELEM> class CONT = std::deque>  // OK 
class Stack { 
  … 
}; 
but the following is not:

template <typename T, 
          template <typename ELEM> typename CONT = std::deque> 
class Stack {                                             // ERROR 
  … 
};

由于上面例子中的ELEM实际中没有用到,其实是可以省略的。

我们实现一个成员函数看看:

template <typename T, template <typename> class CONT> 
void Stack<T,CONT>::push (T const& elem) 
{ 
    elems.push_back(elem);    // append copy of passed elem 
} 

但是如果试图使用上面的stack,编译器会说deque不符合CONT的要求,问题在于,std中的deque要求不只是一个参数,第二个参数是一个配置器,他虽然有预设值,但是当它被用来匹配CONT参数的时候,预设值被编译器忽略了。

对于这个问题,我们可以修改,使得CONT参数要求一个带两个参数的容器。

template <typename T, 
          template <typename ELEM, 
                    typename ALLOC = std::allocator<ELEM> > 
                    class CONT = std::deque> 
class Stack { 
  private: 
    CONT<T> elems;         // elements 
    … 
}; 
最终版本如下:

// basics/stack8.hpp 

#ifndef STACK_HPP 
#define STACK_HPP 

#include <deque> 
#include <stdexcept> 
#include <allocator> 

template <typename T, 
          template <typename ELEM, 
                    typename = std::allocator<ELEM> > 
                    class CONT = std::deque> 
class Stack { 
  private: 
    CONT<T> elems;        // elements 

  public: 
    void push(T const&);  // push element 
    void pop();            // pop element 
    T top() const;         // return top element 
    bool empty() const {   // return whether the stack is empty 
        return elems.empty(); 
    } 

    // assign stack of elements of type T2 
    template<typename T2, 
             template<typename ELEM2, 
                      typename = std::allocator<ELEM2> 
                      >class CONT2> 
    Stack<T,CONT>& operator= (Stack<T2,CONT2> const&); 
}; 

template <typename T, template <typename,typename> class CONT> 
void Stack<T,CONT>::push (T const& elem) 
{ 
    elems.push_back(elem);    // append copy of passed elem 
} 

template<typename T, template <typename,typename> class CONT> 
void Stack<T,CONT>::pop () 
{ 
    if (elems.empty()) { 
        throw std::out_of_range("Stack<>::pop(): empty stack"); 
    } 
    elems.pop_back();         // remove last element 
} 

template <typename T, template <typename,typename> class CONT> 
T Stack<T,CONT>::top () const 
{ 
    if (elems.empty()) { 
        throw std::out_of_range("Stack<>::top(): empty stack"); 
    } 
    return elems.back();      // return copy of last element 
} 
template <typename T, template <typename,typename> class CONT> 
 template <typename T2, template <typename,typename> class CONT2> 
Stack<T,CONT>& 
Stack<T,CONT>::operator= (Stack<T2,CONT2> const& op2) 
{ 
    if ((void*)this == (void*)&op2) {    // assignment to itself? 
        return *this; 
    } 

    Stack<T2> tmp(op2);              // create a copy of the assigned stack 

    elems.clear();                   // remove existing elements 
    while (!tmp.empty()) {           // copy all elements 
        elems.push_front(tmp.top()); 
        tmp.pop(); 
    } 
    return *this; 
} 

#endif // STACK_HPP 
测试如下:

// basics/stack8test.cpp 

#include <iostream> 
#include <string> 
#include <cstdlib> 
#include <vector> 
#include "stack8.hpp" 

int main() 
{ 
    try { 
        Stack<int> intStack;        // stack of ints 
        Stack<float> floatStack;    // stack of floats 

        // manipulate int stack 
        intStack.push(42); 
        intStack.push(7); 

        // manipulate float stack 
        floatStack.push(7.7); 

        // assign stacks of different type 
        floatStack = intStack; 

        // print float stack 
        std::cout << floatStack.top() << std::endl; 
        floatStack.pop(); 
        std::cout << floatStack.top() << std::endl; 
        floatStack.pop(); 
        std::cout << floatStack.top() << std::endl; 
        floatStack.pop(); 
    } 
    catch (std::exception const& ex) { 
        std::cerr << "Exception: " << ex.what() << std::endl; 
    } 

    // stack for ints using a vector as an internal container 
    Stack<int,std::vector> vStack; 
    … 
    vStack.push(42); 
    vStack.push(7); 
    std::cout << vStack.top() << std::endl; 
    vStack.pop(); 
} 
程序的输出为:

7 42 Exception: Stack<>::top(): empty stack 7

目录
相关文章
|
机器学习/深度学习 人工智能 边缘计算
AI技术在医学影像诊断中的应用
传统的医学影像诊断需要耗费大量时间和人力,而随着人工智能技术的发展,AI在医学影像诊断中的应用也日益广泛。本文将探讨AI技术在医学影像诊断中的应用现状和未来发展,以及其对医疗行业的深远影响。
549 28
|
数据采集 数据挖掘 数据处理
进行数据清洗的过程通常包括以下步骤
【4月更文挑战第3天】进行数据清洗的过程通常包括以下步骤
667 3
|
机器学习/深度学习 Python
tanh函数
本文探讨了高等数学中的tanh函数,即双曲正切函数,其定义为 $\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}$,导数为 $1 - \tanh^2(x)$。tanh函数广泛适用于各类场景,并在神经网络中有重要应用。提供的Python代码绘制了tanh函数及其导数的图像。
817 1
|
9月前
|
存储 JavaScript 前端开发
基于 JavaScript/VuePress 搭建的远程工作平台:YuanCheng.works
为了提高团队的协作效率和信息共享能力,许多公司开始探索基于现代技术的远程工作平台。本文将介绍如何利用 JavaScript 和 VuePress 搭建一个高效的远程工作平台,助力团队在灵活的工作环境中实现卓越的协作。
184 56
|
10月前
|
算法 安全 网络安全
阿里云SSL证书双11精选,WoSign SSL国产证书优惠
2024阿里云11.11金秋云创季活动火热进行中,活动月期间(2024年11月01日至11月30日)通过折扣、叠加优惠券等多种方式,阿里云WoSign SSL证书实现优惠价格新低,DV SSL证书220元/年起,助力中小企业轻松实现HTTPS加密,保障数据传输安全。
789 3
阿里云SSL证书双11精选,WoSign SSL国产证书优惠
|
11月前
|
小程序 开发者 UED
支付宝小程序UI/UX设计原则与最佳实践
支付宝小程序UI/UX设计原则与最佳实践
472 6
|
JavaScript Java 测试技术
基于微信小程序的考研资料分享系统+springboot+vue.js附带文章和源代码设计说明文档ppt
基于微信小程序的考研资料分享系统+springboot+vue.js附带文章和源代码设计说明文档ppt
171 0
|
安全 网络安全 网络虚拟化
GRE和IPsec搭配使用,到底是谁over谁?先看GRE over IPsec
GRE和IPsec搭配使用,到底是谁over谁?先看GRE over IPsec
GRE和IPsec搭配使用,到底是谁over谁?先看GRE over IPsec
|
API
对企业用户信息进行认证的几种方式
企业认证的方式有很多种,根据业务类型和平台定位的不同,分为多种不同的形式,一般是通过人工审核和接入数据服务商的数据认证接口进行信息验证,具体常见的认证方式有以下几种。
435 0
对企业用户信息进行认证的几种方式
|
人工智能 搜索推荐 机器人
神奇智能搜索引擎:perplexity智能搜索引擎(ChatGPT与Edge合体——联网版chatGPT)
神奇智能搜索引擎:perplexity智能搜索引擎(ChatGPT与Edge合体——联网版chatGPT)