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

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 艾斯維亞 閱讀(298) 評論(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>
            亚洲第一狼人社区| 亚洲网站在线看| 免费成人av| 亚洲国产黄色| 亚洲第一伊人| 欧美激情综合网| 亚洲一区二区黄色| 午夜久久久久久| 极品尤物一区二区三区| 亚洲大片精品永久免费| 欧美日韩精品在线播放| 香蕉久久夜色精品国产| 欧美一站二站| 亚洲精品一区二区三区婷婷月| 亚洲人成在线观看一区二区| 国产精品伦理| 久久久综合精品| 欧美激情成人在线| 亚洲欧美日韩中文视频| 久久精品网址| 亚洲精品一区二区网址| 亚洲一区精彩视频| 怡红院精品视频| 136国产福利精品导航网址应用| 亚洲视频一区二区在线观看| 亚洲女人天堂成人av在线| 在线观看日产精品| 99国产精品视频免费观看一公开| 国产精品美女久久福利网站| 免费成人毛片| 欧美午夜精品久久久久久超碰| 久久久久高清| 欧美国产视频一区二区| 欧美一区二区三区免费视| 另类国产ts人妖高潮视频| 亚洲一区二区日本| 久久久久久免费| 亚洲一区亚洲| 狂野欧美一区| 欧美一区二区三区四区高清 | 牛夜精品久久久久久久99黑人| 欧美日韩1区2区| 久久久久一区二区三区四区| 欧美日本三区| 另类激情亚洲| 国产精品久久久一区麻豆最新章节 | 美女日韩在线中文字幕| 午夜精品久久| 欧美肥婆在线| 久久美女艺术照精彩视频福利播放| 欧美精品一线| 久久一区视频| 国产精品美女久久久久久2018 | av成人老司机| 久久9热精品视频| 中文在线资源观看网站视频免费不卡| 久久激情网站| 亚洲一区二区三区午夜| 狂野欧美性猛交xxxx巴西| 久久国产主播| 欧美午夜不卡在线观看免费| 欧美成人综合网站| 国产日韩亚洲欧美| 99国产精品久久久久老师| 91久久精品网| 久久久精品一品道一区| 性色av香蕉一区二区| 欧美精品久久久久久| 免费人成网站在线观看欧美高清| 国产精品网曝门| 亚洲日本va在线观看| 一区二区三区在线视频播放| 亚洲欧美一区二区精品久久久| 一区二区三区高清在线| 美女黄毛**国产精品啪啪| 久久久久国产一区二区| 国产精品网站在线| 日韩小视频在线观看专区| 亚洲国产乱码最新视频| 久久久久久久久久久久久女国产乱| 午夜久久tv| 欧美视频精品在线| 亚洲韩国日本中文字幕| 亚洲国产精品悠悠久久琪琪 | 免费成人高清在线视频| 久久婷婷一区| 国产婷婷色一区二区三区四区 | 日韩系列在线| 亚洲免费在线看| 欧美极品在线视频| 亚洲国产高清自拍| 亚洲福利精品| 久久久精品国产一区二区三区| 欧美在线亚洲在线| 国产精品有限公司| 亚洲小说欧美另类婷婷| 亚洲综合999| 国产精品久久久久77777| 99国产精品久久久久久久成人热| 日韩视频一区二区三区在线播放| 欧美成人精品福利| 欧美电影美腿模特1979在线看| 影音先锋一区| 久久婷婷国产综合国色天香| 免费看成人av| 亚洲国产高清高潮精品美女| 理论片一区二区在线| 欧美国产视频在线| 亚洲啪啪91| 欧美激情网友自拍| 亚洲精选在线观看| 一区二区三区日韩欧美精品| 欧美日韩高清在线播放| 一区二区国产在线观看| 亚洲综合国产激情另类一区| 国产精品久久一级| 亚洲欧美日韩国产中文| 久久av一区二区三区| 国产私拍一区| 久久亚洲国产成人| 亚洲电影在线观看| 99精品国产福利在线观看免费 | 欧美一区二区黄色| 国产亚洲精品久久久久动| 久久国产精品色婷婷| 欧美+日本+国产+在线a∨观看| 亚洲国产欧美一区二区三区同亚洲 | 国产欧美日韩一区二区三区在线| 欧美一区二区三区喷汁尤物| 久久这里只有精品视频首页| 亚洲国产精品久久久久秋霞蜜臀 | 国产精品xnxxcom| 亚洲综合激情| 久久久久综合网| 亚洲国产精品va在线看黑人动漫| 欧美黄色片免费观看| 夜夜嗨av一区二区三区| 欧美一区二区三区在线观看| 韩国自拍一区| 毛片基地黄久久久久久天堂| 亚洲精品久久久久久下一站 | 99re亚洲国产精品| 欧美性大战久久久久久久蜜臀| 午夜精品影院| 亚洲第一狼人社区| 亚洲欧美日韩区| 狠狠色狠色综合曰曰| 欧美激情一区二区三区高清视频| 一区二区三区免费看| 欧美中文字幕久久| 亚洲国产精品一区二区第一页| 欧美日韩国产影片| 先锋影院在线亚洲| 亚洲第一区在线| 亚洲欧美综合另类中字| 在线电影欧美日韩一区二区私密| 欧美精品情趣视频| 午夜国产精品影院在线观看 | 亚洲乱码国产乱码精品精天堂 | 亚洲一区二区黄| 老牛影视一区二区三区| 日韩写真视频在线观看| 国产欧美va欧美va香蕉在| 快播亚洲色图| 一区二区三区欧美日韩| 久久久久久久久久久久久9999| 亚洲人成亚洲人成在线观看图片| 国产精品国产精品国产专区不蜜| 久久久久看片| 一区二区欧美在线观看| 蜜桃精品一区二区三区| 亚洲制服丝袜在线| 在线观看日韩欧美| 国产精品电影在线观看| 麻豆成人综合网| 亚洲一区免费| 欧美激情国产日韩| 欧美一区=区| 日韩午夜精品视频| 国精品一区二区三区| 欧美日韩中文字幕在线| 久久婷婷色综合| 亚洲欧美电影在线观看| 亚洲激情网址| 久久综合九色九九| 亚洲专区一区| 亚洲美女视频在线观看| 韩国av一区二区| 国产精品另类一区| 欧美精品一区二区三区视频| 久久成人国产| 亚洲永久字幕| 日韩午夜精品| 亚洲国产1区| 久热这里只精品99re8久| 午夜久久福利| 亚洲精品1区2区| 好看的日韩视频| 国产欧美精品久久| 欧美色图一区二区三区|