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

posts - 297,  comments - 15,  trackbacks - 0

[Originally written sometime in December, 2006. Fixed a couple markup errors, changed some wording, and added a little bit 12/23/2007. I still don't quite consider it complete; I haven't explained all the rules yet. I have a ranty version of what I want to add here; start reading where it says "[RESUMING]" if you read this document first.]

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;
...
}

from:
http://pages.cs.wisc.edu/~driscoll/typename.html
posted on 2010-04-19 11:58 chatler 閱讀(471) 評論(0)  編輯 收藏 引用 所屬分類: Template
<2010年4月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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免费观看| 91久久亚洲| 久久精品一区| 欧美一区二区三区免费看 | 久久精品国产亚洲aⅴ| 国产精品久久久久久久午夜片| 亚洲欧美一区二区三区在线| 一区二区激情视频| 国产午夜精品久久久久久免费视| 久久亚洲风情| 欧美精品自拍偷拍动漫精品| 亚洲视频综合在线| 欧美在线观看一二区| 91久久精品国产91久久性色tv | 午夜免费电影一区在线观看| 欧美影院在线播放| 亚洲区第一页| 亚洲免费网址| 亚洲国产毛片完整版| 一本大道久久精品懂色aⅴ| 国产一区导航| 亚洲精品日本| 激情偷拍久久| 亚洲素人在线| 亚洲黄色影院| 欧美一级片久久久久久久| 亚洲狼人综合| 久久久久久久久久久久久9999| 一本色道久久综合亚洲精品不 | 国产精品中文字幕欧美| 亚洲国产精品999| 国产精品一区二区久久国产| 亚洲国产欧美在线人成| 国产中文一区二区| 夜夜嗨av一区二区三区| 亚洲国产一区在线观看| 欧美一区久久| 午夜视频一区二区| 欧美日本韩国| 亚洲高清资源| 亚洲第一网站| 久久久久国产精品午夜一区| 欧美亚洲一区二区在线观看| 欧美日韩另类视频| 亚洲国产成人久久综合一区| 尤物yw午夜国产精品视频| 亚洲女同同性videoxma| 亚洲一区二区三区午夜| 欧美激情一区二区三区四区| 六月婷婷久久| 好吊日精品视频| 先锋影院在线亚洲| 久久成人精品无人区| 国产精品久久国产三级国电话系列 | 性欧美办公室18xxxxhd| 欧美日韩国产综合一区二区| 欧美激情aⅴ一区二区三区| 激情另类综合| 久久久午夜电影| 免费欧美高清视频| 在线成人亚洲| 美女视频网站黄色亚洲| 欧美成人xxx| 亚洲国产日韩欧美在线图片 | 一区二区三区四区蜜桃| 亚洲午夜精品久久久久久app| 欧美日韩国产精品专区| 日韩视频免费| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美色图麻豆| 亚洲欧美国产精品桃花| 久久激情视频久久| 黄色成人小视频| 可以看av的网站久久看| 亚洲黄色片网站| 亚洲一区在线直播| 国产一区二区三区直播精品电影| 欧美在线关看| 欧美激情精品久久久久久大尺度 | 欧美怡红院视频一区二区三区| 国产模特精品视频久久久久| 久久国产精品久久久久久| 欧美18av| 亚洲综合首页| 国产日韩欧美| 奶水喷射视频一区| 中文国产成人精品| 久久躁狠狠躁夜夜爽| 亚洲最新视频在线| 国产欧美日韩免费| 毛片av中文字幕一区二区| 亚洲免费观看| 久久亚洲私人国产精品va| 亚洲精选久久| 国产香蕉久久精品综合网| 欧美成人中文| 午夜在线视频观看日韩17c| 欧美第一黄网免费网站| 亚洲手机在线| 亚洲国产精品尤物yw在线观看| 欧美日韩免费区域视频在线观看| 欧美一区1区三区3区公司| 亚洲国产美女| 久久视频在线视频| 亚洲综合999| 亚洲黄色在线视频| 国产午夜亚洲精品不卡| 欧美日韩视频在线第一区| 久久久久91| 亚洲女人av| 日韩视频亚洲视频| 欧美国产日韩一区二区在线观看| 亚洲欧美在线aaa| 日韩视频一区二区在线观看 | 亚洲国产欧美一区二区三区久久 | 亚洲激情专区| 男男成人高潮片免费网站| 亚洲一区二区三区精品在线 | 激情成人在线视频| 国产日本亚洲高清| 欧美视频在线不卡| 欧美日韩高清在线一区| 欧美成人精品福利| 久久久久久久久伊人| 午夜欧美电影在线观看| 亚洲一区二区在线看| 亚洲美洲欧洲综合国产一区| 欧美mv日韩mv国产网站| 久久久久久精| 久久精品日产第一区二区三区| 亚洲性感美女99在线| 一区二区精品在线| 99热在线精品观看| 99热精品在线| 亚洲图片欧美午夜| 亚洲综合精品| 性伦欧美刺激片在线观看| 亚洲欧美日韩精品久久亚洲区| 亚洲私人黄色宅男| 亚洲影音先锋| 欧美一区午夜精品| 久久九九久久九九| 久久婷婷综合激情| 久久综合亚洲社区| 欧美成人一区二免费视频软件| 蜜乳av另类精品一区二区| 女生裸体视频一区二区三区| 欧美福利在线| 亚洲精品视频在线观看网站| 亚洲日本免费电影| 国产精品99久久久久久久女警 | 欧美午夜精品电影| 国产美女精品视频| 一区二区在线观看视频| 91久久精品美女高潮| 夜夜躁日日躁狠狠久久88av| 亚洲一区二区黄色| 欧美在线视频免费播放| 久久影视精品| 亚洲第一福利社区| 亚洲乱码国产乱码精品精天堂| 一本到高清视频免费精品| 亚洲欧美日韩爽爽影院| 久久中文字幕一区| 欧美日韩免费在线观看| 国产精品视频网址| 欲色影视综合吧| 亚洲视频自拍偷拍| 久久久高清一区二区三区| 亚洲高清视频一区| 亚洲一卡久久| 欧美暴力喷水在线| 国产精品女主播| 亚洲国产第一页| 欧美一级黄色网| 亚洲国产精品成人精品| 亚洲欧美成人一区二区三区| 麻豆91精品91久久久的内涵| 欧美午夜影院| 亚洲精品国久久99热| 精久久久久久| 玖玖在线精品| 欧美一级专区| 久久这里只精品最新地址| 亚洲第一页自拍| 午夜日韩在线观看| 欧美日韩理论| 尤物99国产成人精品视频| 亚洲欧美国产77777| 欧美国产日韩免费| 亚洲欧美日韩一区二区在线 | 国产精品美女久久福利网站| 激情一区二区三区| 欧美一二三视频| 日韩午夜剧场| 美日韩在线观看| 激情欧美一区二区三区在线观看 | **网站欧美大片在线观看| 亚洲综合视频网| 亚洲免费成人av|