C++ template 学习归纳总结4

我们在这篇文章来说说typename关键字吧。这个关键字是在c++的标准化过程中引入的,目的在于说明template中的某个表示符号是一个类型,而不是其他的东西,看下面的代码:

template <typename T>
class MyClass {
   typename T::SubType * ptr;
   …
};

第一个typename我就不多说了,大家都知道,我来说一下第二个。他的意思是说T::SubType是class T内部定义的一个类型,从而ptr是一个指向【T:SubType类型】的指针。

如果在上面的代码中,没有第二个typename关键字的话,编译器会以为SubType是class Type的一个static成员。于是会被编译器理解为一个具体的东西,从而导致T::SubType * ptr 所表达的意思是两个数进行相乘。

关于这个知识的应用比较多的是STL中,比如:

#include <iostream> 

// print elements of an STL container
template <typename T>
void printcoll (T const& coll)
{
    typename T::const_iterator pos;  // iterator to iterate over coll
    typename T::const_iterator end(coll.end());  // end position 

    for (pos=coll.begin(); pos!=end; ++pos) {
        std::cout << *pos << ' ';
    }
    std::cout << std::endl;
} 

下面我们来看看另外一个有意思的问题。那就是”.template”,大家仔细查看下面的代码:

template<int N>
void printBitset (std::bitset<N> const& bs)
{
    std::cout << bs.template to_string<char,char_traits<char>,
                                       allocator<char> >();
}

大家注意到没有,。这个例子中的“.template”比较怪,但是如果没有他的话,那么编译器无法知道后面的“<”是模板参数的开始。而不是一个小于号。注意,只有当位于 点号之前的物件取决于某一个template parameter的时候,这种情况才会发生,以上的例子中,bs受控于N。也就是显式指明模板函数调用。可以理解为指名点姓的调用模板成员函数而非普通的。

结论是“.template”或者”->template”记号只能在templates中使用。而且他们必须紧跟在于template parameter相关的某个物件。

其实这里关于这个”.template”,笔者也没有搞懂,不知道哪位大牛搞懂了,麻烦指教一下,谢谢了。

下面我们来看看成员模板:

先看看下面的例子:

 

Stack<int> intStack1, intStack2;   // stacks for ints
Stack<float> floatStack;           // stack for floats
…
intStack1 = intStack2;   // OK: stacks have same type
floatStack = intStack1;  // ERROR: stacks have different types

默认的赋值运算要求左右两边拥有相等的类型。但是如果把赋值运算定义为一个模板,就可以使得类型不同,但是元素可以隐式转换,比如:

template <typename T>
class Stack {
  private:
    std::deque<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>
    Stack<T>& operator= (Stack<T2> const&);
}; 

我们来实现它看看:关键代码如下:

template <typename T>
 template <typename T2>
Stack<T>& Stack<T>::operator= (Stack<T2> 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;
} 

下面我们测试一下啊:

Stack<int> intStack;     // stack for ints
Stack<float> floatStack; // stack for floats
…
floatStack = intStack;   // OK: stacks have different types,
                         //     but int converts to float

当然这个运算并不改变stack和其元素的类型,赋值完成转换,floatstack返回的任然是float。但是这个技术并不是说任何两个类型都能进行赋值,比如下面的代码就不行:

Stack<std::string> stringStack;  // stack of ints
Stack<float>       floatStack;   // stack of floats
…
floatStack = stringStack;  // ERROR: std::string doesn't convert to float 

你知道为什么了吗?

当然,和以前一样,你也可以在将内部容器的类型也参数化:

template <typename T, typename CONT = std::deque<T> >
class Stack {
  private:
    CONT 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, typename CONT2>
    Stack<T,CONT>& operator= (Stack<T2,CONT2> const&);
}; 

此时的赋值运算实现代码为:

template <typename T, typename CONT>
 template <typename T2, typename 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;
} 
时间: 2024-11-01 01:03:27

C++ template 学习归纳总结4的相关文章

C++ template 学习归纳2

关于c++中的类模板,常见的形式为: template<typename T> class className{ //... }; 比如笔者在这里举一个例子:   #include <iostream> #include<vector> #include <stdexcept> template<typename T> class stack{ private: std::vector<T> elems; public: void p

C++ template学习总结6

对于基本类型来说,并没有一个default模式来讲他们初始化为有意义的值,没有初始化的变量,其指都是未定义的,但是在模板这一块呢?我们可以采用下面的形式: template <typename T> void foo() { T x = T(); // x is zero (or false)ifT is a built-in type } 对于class template我们可以采用下面例子的方式: template <typename T> class MyClass { pr

c++ template学习总结3

和往常一样,先来看一段代码: #include <stdexcept> template <typename T, int MAXSIZE> class Stack { private: T elems[MAXSIZE]; // elements int numElems; // current number of elements public: Stack(); // constructor void push(T const&); // push element vo

jQuery .tmpl(), .template()学习资料小结_jquery

昨晚无意中发现一个有趣的jQuery插件.tmpl(),其文档在这里.官方解释对该插件的说明:将匹配的第一个元素作为模板,render指定的数据,签名如下: .tmpl([data,][options]) 其中参数data的用途很明显:用于render的数据,可以是任意js类型,包括数组和对象.options一般情况下都是选项了,官方指出,此处的options是一个用户自定义的键值对的map,继承自tmplItem数据结构,适用于模板render动作期间. 在这里可以下载到最新的tmpl插件,值

快速读懂机器学习(附送详细学习资源)

前言: 机器学习作为人工智能中的伟大分支,让我们先来聊聊人工智能把.现在人工智能已经非常普遍了,从之前的阿尔法狗到现在中国人工智能机器人解答北京高考数学卷 考了105分.以及2017.6.6的苹果WWDC大会上宣布开发机器学习API,苹果想通过借此之举,让更过苹果开发者用户开发出更过用户体验好的应用,人工智能的例子真是数不胜数,已经渗透到我们生活的各方各面,比较常见的比如金融以及医疗,而且之前看了一篇文章这样评价金融业:随着人工智能的发展与普遍,以后金融业对求职者的要求需要掌握人工智能相关知识来

AI 初学者入门指南:深度学习的五级分类

目前 AI 被笼统划分为"弱人工智能"."强人工智能"."超人工智能"三个类别.甚至在很多业内专家(比如洪小文)眼中,只有"强"."弱"AI 的区别,因为"超人工智能"离我们实在还很远,难以捉摸.这样的笼统分类显然不利于大众对于各项 AI 技术进行认识和理解.因此,一些专家开始提出基于技术难度和 AI 智能水平的分类.分级方法. 其中,美国学者 Arend Hintze 提出了对 AI

机器学习——随机森林算法及原理

1. 随机森林使用背景 1.1 随机森林定义 随机森林是一种比较新的机器学习模型.经典的机器学习模型是神经网络,有半个多世纪的历史了.神经网络预测精确,但是计算量很大.上世纪八十年代Breiman等人发明分类树的算法(Breiman et al. 1984),通过反复二分数据进行分类或回归,计算量大大降低.2001年Breiman把分类树组合成随机森林(Breiman 2001a),即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树的结果.随机森林在运算量没有显著提

深度 | 人工智能全局概览:通用智能的当前困境和未来可能

我们的未来将不可避免地与人工智能捆绑在一起,于是我们就必须要问:人工智能的现状是怎样的?我们将走向何方?(可点击阅读原文下载原版 PDF) 目录 如今人工智能的能力和局限 迈向通用人工智能 训练还是不训练 智能的意义 助理还是主角? 为何人们对人工智能的兴趣大增? 建立知识数据库 产生结果 道德和未来 总是在未来 定义人工智能不是困难,而简直是不可能,这完全不是因为我们并不理解人类智能.奇怪的是,人工智能的进步更多的将帮助我们定义人类智能不是什么,而不是定义人工智能是什么? 但不管人工智能是什么

中国人工智能学会通讯——智能交互开启未来

我讲的内容可能跟刘博士有一部分是重复的.因为之前我们一直做语义理解,语音识别厂商一直在做语音,后来大家发现它们密不可分,所以一直在融合.我们现在在找语音方面的一些合作伙伴,语音厂商也往语义方面去做. 人工智能,对于普通的群众来说就是变形金刚,就是终结者.可是在产业界,我们就会想到自动驾驶,还有机器识别,还有类似的智能交互,还有AlphaGO.人工智能其实不是全能的,只是在某一个方向.某一个方面去解决一定的问题.我们怎么去定义人工智能?现在人工智能没有一个非常明确的定义,没有非常明确官方的定义,因