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

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>
            国产精品丝袜xxxxxxx| 久久精品盗摄| 欧美日本高清| av成人福利| 亚洲天堂成人| 国产一区二区三区高清播放| 久久久久高清| 你懂的成人av| 亚洲精品视频在线播放| av成人激情| 国产欧美日韩三级| 在线看片欧美| 久久综合九色| 蘑菇福利视频一区播放| 99这里只有精品| 亚洲自拍高清| 亚洲国产成人精品女人久久久 | 欧美黄色网络| 欧美日韩精品三区| 久久精品国产999大香线蕉| 久久久久综合网| 99亚洲视频| 久久国产精品亚洲77777| 亚洲精品一区二区三区福利| 亚洲午夜久久久久久久久电影院| 国产专区欧美专区| 亚洲三级电影全部在线观看高清| 国产精品久久久久久久久动漫| 亚洲欧美日韩综合| 国产日韩欧美一二三区| 午夜精品福利电影| 久久免费的精品国产v∧| 久久久久久伊人| 香蕉视频成人在线观看| 欧美日韩美女| 亚洲激情第一页| 国产揄拍国内精品对白| 在线视频亚洲一区| 亚洲综合色视频| 亚洲欧美日韩一区在线| 久久国产色av| 欧美日韩成人一区| 久久久国产精品亚洲一区 | 亚洲在线国产日韩欧美| 久久精品视频99| 亚洲欧美另类中文字幕| 欧美不卡高清| 美女视频黄a大片欧美| 国产精品免费一区二区三区观看| 亚洲国产成人精品久久久国产成人一区| 国产精品黄色| 日韩一级二级三级| 一本在线高清不卡dvd| 久久综合狠狠| 欧美aa国产视频| 好吊色欧美一区二区三区四区| 亚洲一区二区3| 亚洲一区国产视频| 欧美色欧美亚洲另类七区| 欧美激情欧美狂野欧美精品| 一区免费在线| 久久久久久久久综合| 久久天天躁狠狠躁夜夜av| 国产日韩欧美精品| 欧美亚洲一区二区在线| 欧美影院成年免费版| 国产精品入口日韩视频大尺度| 夜夜爽www精品| 亚洲综合999| 国产精品久久二区| 亚洲一区美女视频在线观看免费| 亚洲性视频h| 国产精品日韩欧美一区| 亚洲视频狠狠| 欧美在线一区二区三区| 国产视频丨精品|在线观看| 欧美一区二区三区在线视频| 久久精品一区蜜桃臀影院| 国精产品99永久一区一区| 久久久久久一区| 亚洲观看高清完整版在线观看| 亚洲精品一区二| 欧美午夜精品久久久久久孕妇| 亚洲综合色婷婷| 免费观看成人网| 亚洲乱码国产乱码精品精可以看| 欧美精品一区二| 中文日韩欧美| 久久久另类综合| 亚洲精品乱码久久久久久日本蜜臀| 欧美人与性动交a欧美精品| 中国成人在线视频| 老司机亚洲精品| 99这里只有久久精品视频| 国产精品视频yy9299一区| 久久国产一二区| 亚洲精品社区| 久久精品亚洲精品国产欧美kt∨| 在线观看一区二区视频| 欧美日韩视频第一区| 午夜精品久久久久久久99热浪潮| 欧美aa国产视频| 亚洲欧美另类国产| 1000部国产精品成人观看| 欧美日韩亚洲综合在线| 久久久91精品| 宅男精品视频| 亚洲第一精品影视| 久久福利精品| 亚洲天堂av在线免费| 伊人久久综合97精品| 欧美日韩美女在线| 久久资源av| 亚洲欧美一区二区三区久久| 最新成人av网站| 久久男女视频| 欧美一级夜夜爽| 在线亚洲欧美视频| 亚洲国产精品久久久久婷婷老年| 国产精品一区二区在线观看网站| 欧美成人一区二免费视频软件| 午夜国产精品视频免费体验区| 亚洲国产va精品久久久不卡综合| 久久精品成人一区二区三区蜜臀| 一区二区高清在线| 亚洲激情午夜| 一区在线视频| 国产日韩欧美一区| 国产精品捆绑调教| 欧美日韩综合久久| 欧美久久视频| 欧美激情精品久久久久久大尺度| 久久久成人网| 欧美中文日韩| 欧美一区2区三区4区公司二百| 在线视频一区观看| 一本色道久久综合| 亚洲伦理在线| 日韩视频在线一区| 亚洲精品资源| 亚洲精品小视频| 91久久嫩草影院一区二区| 欧美激情视频给我| 亚洲国产99| 亚洲欧洲日本mm| 亚洲国产美国国产综合一区二区| 欧美电影在线免费观看网站| 免费不卡在线观看av| 欧美成人激情在线| 亚洲国产高清高潮精品美女| 欧美黑人多人双交| 亚洲国内欧美| 9久re热视频在线精品| 在线中文字幕日韩| 亚洲欧美日韩网| 久久99在线观看| 美女国内精品自产拍在线播放| 蜜臀a∨国产成人精品| 欧美黄色一区二区| 欧美视频二区36p| 国产精品麻豆成人av电影艾秋 | 久久综合国产精品| 欧美成人tv| 欧美午夜激情视频| 国产夜色精品一区二区av| 樱桃成人精品视频在线播放| 亚洲激情社区| 午夜精品短视频| 久久―日本道色综合久久| 欧美激情a∨在线视频播放| 亚洲欧洲日产国产综合网| 一区二区激情| 久久久综合激的五月天| 欧美激情中文字幕乱码免费| 国产精品久久网| 亚洲国产成人精品久久久国产成人一区| 亚洲精品日韩综合观看成人91| 亚洲天堂成人在线视频| 久久久爽爽爽美女图片| 亚洲精华国产欧美| 亚洲欧美综合精品久久成人| 麻豆免费精品视频| 国产精品社区| 亚洲国产精品一区二区第一页| 亚洲午夜高清视频| 免费日韩av片| 亚洲综合色视频| 欧美激情精品久久久久久变态| 国产日韩一区二区三区| 亚洲精品午夜| 老司机久久99久久精品播放免费| 亚洲精品你懂的| 亚洲欧美日韩国产综合在线| 欧美激情精品久久久久久久变态 | 亚洲高清免费在线| 欧美一区二区三区在线免费观看| 亚洲国产精品www| 久久精品五月婷婷| 国产精品久久久久久亚洲毛片| 最新精品在线|