zoukankan      html  css  js  c++  java
  • 类型名称了解typename的双重意义

    这段时间一直在查找类型名称之类的问题,今天正好有机会和大家共享一下.

        先来看上面一个问题:
    在template声明中,使用class和typename有什么不同?
    template<class T>class Widget;
    template<typename T>class Widget;
    抛开使用习气,声明template参数时,单从C++本身的角度来看,使用关键字class或typename没有任何不同。

    但是C++并非把它们完整视为等价,因为存在既有价值,如果完整一样,干嘛费力的搞了两个出来呢,一个岂不是更便利。
    在这里你要知道,有时候你必须使用typename。
    我们先看上面这个函数模板例子:

    template<typename T>
    void print(const T& container)
    {
    	if(container.size()>=1)
    	{
    		T::const_iterator iter(container.begin());
    		int value=*iter;
    		std::cout<<value;
    	}
    }

        这个模板函数的功能是接收一个STL容器为参数。然后将容器中的第一个元素打印出来。

        看起来没什么问题,编译也能通过,如果你亲自测试的话,也会发现可以运行精良。但是在某些极端情况下,呵呵,会发生什么呢?

        我们先来看一个观点:

        T::const_iterator

        iter的类型是T::const_iterator,但是实际上iter是什么是取决于T。

        而const_iterator这个名称的详细含义也是依赖于T的,我们将它称为从属名称。T::const_iterator这个整体是一个嵌套,我们称它为嵌套从属类型名称。因为const_iterator是从属于T的。

        嵌套从属名称可能致使解析困难。我们看上面的代码

        每日一道理
    自己把自己说服了,是一种理智的胜利;自己被自己感动了,是一种心灵的升华;自己把自己征服了,是一种人生的成功。
    template<typename T>
    void print(const T& container)
    {
    	T::const_iterator* m;
    	...
    }

        这里我们声明m为一个局部变量,它是一个指向T::const_iterator的指针。

        但是有一种情况,如果T::const_iterator它不是一个类型,而是T中的一个静态成员变量(确实有这个可能),而这时m碰巧也是一个全局变量(哪有这么巧的事呀!),那上面的代码就不是定义一个指针变量了,而是两个静态变量相乘。

        上面的情况虽然特殊,但确实有可能发生的。所以C++解析器的设计者必须考虑如何防止这个问题。

        C++有个规矩可以解析这一歧义状态:如果解析器在模板中遇到这个嵌套从属名称,它便假设这个名称不是一个类型。除非你明白告诉他。在缺省情况下,嵌套从属名称不是类型。

    template<typename T>
    void print(const T& container)
    {
    	if(container.size()>=1)
    		T::const_iterator iter(container.begin());
    		...
    }

        上面这段程序不是有效的C++代码。iter只有在T::const_iterator是一个类型时才合理,但是我们并没有明白告诉C++,所以它默许它不是一个类型。

        要想告诉C++,明白指定它是一个类型很简单,在前面加上一个typename就行了

    template<typename T>
    void print(const T& container)
    {
    	if(container.size()>=1)
    	typename T::const_iterator iter(container.begin());
    	//明白指定是一个类型
    		...
    }

    文章结束给大家分享下程序员的一些笑话语录: 有一天,一个男人穿越森林的时候,听到一个细微的声音叫住他。他低头一看,是一只青蛙。
    “如果你亲我一下,我会变成一个美丽的公主哦。”男人一言不发,把青蛙捡起来,放入口袋。
    “如果你亲我一下,我会变成一个美丽的公主哦。而且,我会告诉我遇到的每一个人,你是多么聪明和勇敢,你是我的英雄。”男人把青蛙拿出来,对着它微微一笑,又把它放回口袋。
    “如果你亲我一下,我会变成一个美丽的公主,然后我愿意成为你的爱人一星期。”男人又把青蛙拿出来,对着它微微一笑,把它放回口袋。
    “如果你亲我一下,我会变成一个美丽的公主,然后我愿意成为你的爱人一年,而且你可以对我做任何事。”再一次,男人把青蛙拿出来,对着它微微一笑,又把它放回口袋。
      最后,青蛙无力地问:“我开出了这么好的条件,为什么你还不肯吻我?”男人说:“我是一个程序员,我可没时间和什么公主鬼混。不过,拥有一个会说话的青蛙,倒是蛮酷的。”

    --------------------------------- 原创文章 By
    类型和名称
    ---------------------------------

  • 相关阅读:
    观察者模式(Observer)
    外观模式(三层解耦)
    建造者模式(Builder)
    简单工厂
    单例模式(Winform窗体的实现)
    20180213 字符串spilt方法,字符串打包zip方法
    20180212第一发:Python与Json编码解码举例
    Eclipse插件Fat Jar
    java学习之浅谈多线程4SwingWorker
    Android SDK manager 闪退
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3098121.html
Copyright © 2011-2022 走看看