青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

isware

A Description of the C++ typename keyword

from http://pages.cs.wisc.edu/~driscoll/typename.html
The purpose of this document is to describe the reasoning behind the inclusion of the typename keyword in standard C++, and explain where, when, and how it can and can't be used.

A secondary use

There is a use of typename that is entirely distinct from the main focus of this discussion. I will present it first because it is easy. It seems to me that someone said "hey, since we're adding typename anyway, why not make it do this" and people said "that's a good idea."

Most older C++ books, when discussing templates, use the following type of example:

template <class T> ...

I know when I was starting to learn templates, at first I was a little thrown by the fact that T was prefaced by class, and yet it was possible to instantiate that template with primitive types such as int. The confusion was very short-lived, but the use of class in that context never seemed to fit entirely right. Fortunately for my sensibilities, it is also possible to use typename:

template <typename T> ...

This means exactly the same thing as the previous instance. The typename and class keywords can be used interchangeably to state that a template parameter is a type variable (as opposed to a non-type template parameter).

I personally like to use typename in this context because I think it's ever so slightly clearer. And maybe not so much "clearer" as just conceptually nicer. (I think that good names for things are very important.) Some C++ programmers share my view, and use typename for templates. (However, later we will see how it's possible that this decision can hurt readibility.) Some programmers make a distinction between templates that are fully generic (such as the STL containers) and more special purpose ones that can only take certain classes, and use typename for the former category and class for the latter. Others use class exclusively. This is just a style choice.

However, while I use typename in real code, I will stick to class in this document to reduce confusion with the other use of typename.

The real reason for typename

This discussion I think follows fairly closely appendix B from the book C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond by David Abrahams and Aleksey Gurtovoy, though I don't have it in front of me now. If there are any deficiencies in my discussion of the issues, that book contains the clearest description of them that I've seen.

Some definitions

There are two key concepts needed to understand the description of typename, and they are qualified and dependent names.

Qualified and unqualified names

A qualified name is one that specifies a scope. For instance, in the following C++ program, the references to cout and endl are qualified names:

#include <iostream>  int main()  {    std::cout %lt;%lt; "Hello world!" %lt;%lt; std:: endl; }

In both cases, the use of cout and endl began with std::.

Had I decided to bring cout and endl into scope with a using declaration or directive*, they would have been unqualified names, because they would lack the std::.

(* Remember, a using declaration is like using std::cout;, and actually introduces the name cout into the scope that the using appears in. A using directive is of the form using namespace std; and makes names visible but doesn't introduce anything. [12/23/07 -- I'm not sure this is true. Just a warning.])

Note, however, that if I had brought them into scope with using but still used std::cout, it remains a qualified name. The qualified-ness of a name has nothing to do with what scope it's used in, what names are visible at that point of the program etc.; it is solely a statement about the name that was used to reference the entity in question. (Also note that there's nothing special about std, or indeed about namespaces at all. vector<int>::iterator is a nested name as well.)

Dependent and non-dependent names

A dependent name is a name that depends on a template parameter. Suppose we have the following declaration (not legal C++):

template <class T> class MyClass {    int i;    vector<int> vi;    vector<int>::iterator vitr;        T t;    vector<T> vt;    vector<T>::iterator viter; };

The types of the first three declarations are known at the time of the template declaration. However, the types of the second set of three declarations are not known until the point of instantiation, because they depend on the template parameter T.

The names T, vector<T>, and vector<T>::iterator are called dependent names, and the types they name are dependent types. The names used in the first three declarations are called non-dependent names, at the types are non-dependent types.

The final complication in what's considered dependent is that typedefs transfer the quality of being dependent. For instance:

typedef T another_name_for_T;

another_name_for_T is still considered a dependent name despite the type variable T from the template declaration not appearing.

Note: I am not very familiar with the notion of dependent types in the type theory sense, but they are not quite the same thing in any case. My impression is that you could probably argue a C++ template itself is a dependent type in the type-theoretical sense, but the C++ notion of a dependent type is more like the argument to a dependent type in the type-theoretical sense.

Some other issues of wording

Note that while there is a notion of a dependent type, there is not a notion of a qualified type. A type can be unqualified in one instance, and qualified the next; the qualification is a property of a particular naming of a type, not of the type itself. (Indeed, when a type is first defined, it is always unqualified.)

However, it will be useful to refer to a qualified type; what I mean by this is a qualified name that refers to a type. I will switch back to the more precise wording when I talk about the rules of typename.

The problem

So now we can consider the following example:

template <class T> void foo() {    T::iterator * iter;    ... }

What did the programmer intend this bit of code to do? Probably, what the programmer intended was for there to be a class that defined a nested type called iterator:

class ContainsAType {    class iterator { ... }:    ... };

and for foo to be called with an instantiation of T being that type:

foo<ContainsAType>();

In that case, then line 3 would be a declaration of a variable called iter that would be a pointer to an object of type T::iterator (in the case of ContainsAType, int*, making iter a double-indirection pointer to an int). So far so good.

However, what the programmer didn't expect is for someone else to come up and declare the following class:

class ContainsAValue {    static int iterator; };

and call foo instantiated with it:

foo<ContainsAValue>();

In this case, line 3 becomes a statement that evaluates an expression which is the product of two things: a variable called iter (which may be undeclared or may be a name of a global) and the static variable T::iterator.

Uh oh! The same series of tokens can be parsed in two entirely different ways, and there's no way to disambiguate them until instantiation. C++ frowns on this situation. Rather than delaying interpretation of the tokens until instantiation, they change the languge:

Before a qualified dependent type, you need typename

To be legal, assuming the programmer intended line 3 as a declaration, they would have to write

template <class T> void foo() {    typename T::iterator * iter;    ... }

Without typename, there is a C++ parsing rule that says that qualified dependent names should be parsed as non-types even if it leads to a syntax error. Thus if there was a variable called iter in scope, the example would be legal; it would just be interpreted as multiplication. Then when the programmer instantiated foo with ContainsAType, there would be an error because you can't multiply something by a type.

typename states that the name that follows should be treated as a type. Otherwise, names are interpreted to refer to non-types.

This rule even holds if it doesn't make sense even if it doesn't make sense to refer to a non-type. For instance, suppose we were to do something more typical and declare an iterator instead of a pointer to an iterator:

template <class T> void foo() {    typename T::iterator iter;    ... }

Even in this case, typename is required, and omitting it will cause compile error. As another example, typedefs also require use:

template <class T> void foo() {    typedef typename T::iterator iterator_type;    ... }

posted on 2011-06-28 17:17 艾斯維亞 閱讀(289) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美精品在线观看91| 欧美大片一区二区三区| 国产精品尤物福利片在线观看| 亚洲欧洲一区二区天堂久久| 亚洲黄色三级| 欧美日韩a区| 午夜精品国产更新| 亚洲欧美日韩精品久久| 国产一区二区丝袜高跟鞋图片| 久久久欧美精品sm网站| 久久久精品动漫| 亚洲乱码国产乱码精品精98午夜| 亚洲精品亚洲人成人网| 国产精品国产馆在线真实露脸 | 国产一区二区欧美| 欧美高清影院| 国产精品高潮粉嫩av| 久久久久久尹人网香蕉| 欧美va亚洲va日韩∨a综合色| 亚洲午夜精品久久| 午夜精品一区二区三区电影天堂| 国精品一区二区| 亚洲全黄一级网站| 国产农村妇女精品| 欧美激情在线观看| 国产精品爽黄69| 欧美韩日一区| 国产精品视频99| 欧美国产三区| 国产欧美一区二区色老头| 欧美福利视频| 国产日韩欧美在线一区| 亚洲二区在线| 国产亚洲精品资源在线26u| 亚洲激情影院| 精品动漫3d一区二区三区| 一区二区三区欧美日韩| 亚洲高清二区| 欧美在线短视频| 亚洲欧美成aⅴ人在线观看| 可以看av的网站久久看| 欧美中文字幕在线| 国产精品vip| 亚洲伦理自拍| 亚洲欧洲日本在线| 欧美在线视频a| 午夜免费在线观看精品视频| 欧美高清视频www夜色资源网| 久久久欧美精品| 国产精品视频成人| 99在线观看免费视频精品观看| 136国产福利精品导航网址| 欧美伊人久久久久久久久影院| 亚洲欧美成人精品| 欧美日韩在线高清| 亚洲卡通欧美制服中文| 亚洲国产高清高潮精品美女| 欧美中文字幕在线| 久久久无码精品亚洲日韩按摩| 欧美三级小说| 一区二区三区免费观看| 亚洲视频福利| 欧美体内谢she精2性欧美| 亚洲激情国产| 99re国产精品| 欧美理论在线| 日韩天堂在线观看| 亚洲特级毛片| 国产精品第三页| 亚洲先锋成人| 欧美一区二区三区久久精品| 国产精品视频xxx| 香蕉精品999视频一区二区| 欧美在线视频不卡| 韩国在线一区| 免费成人黄色片| 亚洲黄色av一区| 夜夜爽av福利精品导航| 国产精品porn| 香蕉久久夜色| 欧美二区在线| 亚洲网站在线播放| 国产精品一区二区在线观看| 小黄鸭精品aⅴ导航网站入口| 久久久久国产一区二区三区| 亚洲高清电影| 欧美午夜不卡视频| 香蕉久久a毛片| 亚洲第一精品夜夜躁人人躁| 99在线观看免费视频精品观看| 国产精品成人一区二区| 欧美在线观看视频在线| 欧美国产日韩二区| 亚洲在线一区二区三区| 韩国三级电影久久久久久| 久久综合伊人| 中文av字幕一区| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲精品国精品久久99热一| 国产精品久久福利| 久久久av毛片精品| 一区二区高清视频在线观看| 久久午夜av| 亚洲一区二区黄| 在线观看亚洲精品视频| 国产精品福利网站| 玖玖玖免费嫩草在线影院一区| 一区二区三区不卡视频在线观看| 久久久噜噜噜久久狠狠50岁| 中日韩美女免费视频网址在线观看 | 国内精品久久久久久久97牛牛| 欧美成人综合一区| 香蕉久久精品日日躁夜夜躁| 亚洲人成网站色ww在线| 久久久91精品国产| 亚洲一区二区三区视频| 亚洲国内高清视频| 国产日产精品一区二区三区四区的观看方式| 久久一区二区三区av| 亚洲男女毛片无遮挡| 亚洲精品1区| 欧美**人妖| 久久久水蜜桃| 欧美在线亚洲| 午夜精品在线观看| 在线视频欧美精品| 亚洲精品婷婷| 亚洲娇小video精品| 黄色另类av| 国产有码一区二区| 国产精品久久久久久模特| 欧美人与性动交cc0o| 欧美.www| 久久久久久久精| 欧美亚洲在线观看| 亚洲欧美日韩在线一区| 亚洲午夜精品久久| 一本一本a久久| 日韩一级在线观看| 亚洲视频中文字幕| 亚洲自拍16p| 亚洲欧美资源在线| 亚洲欧美综合v| 欧美影院精品一区| 欧美在线精品免播放器视频| 午夜亚洲性色视频| 久久成人免费视频| 久久国产加勒比精品无码| 欧美淫片网站| 久久琪琪电影院| 六月婷婷一区| 免费的成人av| 欧美精品一二三| 欧美日韩亚洲三区| 国产精品日本一区二区| 国产精品免费久久久久久| 国产乱码精品一区二区三区不卡 | 国产欧美日韩在线观看| 国产日韩欧美一区二区三区在线观看| 国产日韩欧美三区| 亚洲第一精品影视| 一本大道久久a久久精二百| 亚洲一区在线观看视频| 久久国产成人| 亚洲国产另类 国产精品国产免费| 欧美不卡福利| 夜夜爽av福利精品导航 | 亚洲欧美三级在线| 久久视频免费观看| 欧美日韩一区在线观看视频| 国产欧美日韩免费看aⅴ视频| 在线观看亚洲视频啊啊啊啊| 亚洲欧洲一区二区在线播放| 亚洲欧美激情在线视频| 久久午夜视频| 一区二区三区欧美激情| 久久亚洲影院| 国产精品美女在线| 最近中文字幕日韩精品| 欧美一区二区黄色| 亚洲国产第一| 亚洲一区一卡| 中国女人久久久| 亚洲黄页视频免费观看| 亚洲午夜激情| 亚洲自拍啪啪| 欧美黄在线观看| 国产精品青草久久久久福利99| 国产视频一区二区在线观看| 亚洲免费大片| 久久精品午夜| 亚洲经典三级| 久久精品99国产精品酒店日本| 欧美二区不卡| 国产精品一区二区在线观看网站 | 欧美精品观看| 国产视频在线观看一区| 亚洲精品永久免费精品| 久久久久久亚洲综合影院红桃 | 亚洲精品视频啊美女在线直播|