1. 程式人生 > >C++之typename

C++之typename

1、typename和class

在模板前,typename和class沒有區別

template<typename T> class A;
template<class T> class A;
typename和class對編譯器而言卻是不同的東西

2、宣告一個型別

看下面的程式碼

我們編譯下結果如下


編譯器不知道T::const_iterator是個型別。如果它是個變數呢? T::const_iterator的解析有著邏輯上的矛盾: 直到確定了T是什麼東西,編譯器才會知道
T::const_iterator是不是一個型別; 然而當模板被解析時,T還是不確定的。這時我們宣告它為一個型別才能通過編譯:

加上typename 編譯就沒問題了

typename T::const_iterator it = container.begin();

我們在來分析下面的例子
#include <iostream>

using namespace std;

template <class T>

class CInstance 
{

private:

    struct object_creator {
        object_creator() 
        {
            CInstance<T>::GetInstance();
        }
    inline void do_nothing(){}
    };

    static object_creator create_object;

public:
    static T& GetInstance() 
    {
         static T instance;
         create_object.do_nothing();
         return instance;
    }

protected:
    CInstance(){}

private:
    CInstance(const CInstance& c);
    CInstance operator = (const CInstance& c);
};

#include <iostream>
using namespace std;
template <class T>
class C
{
private:
   struct B {
       B() {
         A<T>::getInstance();
       }
       void do(){}
   };
   static creator create;
public:
    static T& getInstanc() {
       static T t;
       create.do();
       return t;
    }
};

//如果類繼承了這個函式,需到得到類的例項,會呼叫getInstance(),但是getInstance()函式裡面又有create_object.do(),所以我們這裡需要用typename宣告create_object,程式碼如下

template <typename T>
typename CInstance<T>::creator CInstance<T>::create;
如果別人呼叫就按照下面方式

class A : public CInstance <class A> {
public:
    void test()
    {
        cout<<"a is "<<a<<endl;
    }  
    int a;
};

int main()
{
   A& a = A::GetInstance();
   a.a = 3;
   a.test();
   return 0;
}

上面也使用了typename聲明瞭。

3、巢狀從屬名稱


事實上型別C::const_iterator依賴於模板引數C, 模板中依賴於模板引數的名稱稱為從屬名稱(dependent name), 當一個從屬名稱巢狀在一個類裡面時,稱為巢狀從屬名稱(nested dependent name)。 其實C::const_iterator還是一個巢狀從屬型別名稱(nested dependent type name)。

巢狀從屬名稱是需要用typename宣告的,其他的名稱是不可以用typename宣告的。比如下面是一個合法的宣告:

template<typename C>
void f(const C& container, typename C::iterator iter);


如果你把const C&也聲明瞭typename也是要編譯錯的哦:

template<typename C>
void f(typename const C& container, typename C::iterator iter);

錯誤輸出:

4、在派生子類的基類列表中,以及建構函式的基類初始化列表中,不允許typename宣告

相關推薦

C++typename

1、typename和class 在模板前,typename和class沒有區別 template<typename T> class A; template<class T> class A; typename和class對編譯器而言卻是不同的東西

C# 集合ArrayList

img 必須 () pac range tro 我們 list() 叠代 .NET Framework提供了用於數據存儲和檢索的專用類,這些類統稱集合。這些類提供對堆棧、隊列、列表和哈希表的支持。大多數集合類實現系統的接口。以下我們主要來講一下ArrayList。

C#自定義特性

創建 tip comm 字段 運算符 包含 自動 名稱 程序   在前面介紹的代碼中有使用特性,這些特性都是Microsoft定義好的,作為.NET Framework類庫的一部分,許多特性都得到了C#編譯器的支持。   .NET Frmework也允許定義自己的特性。自

C++Binary Heap/Max Heap

right pac col log parent this success ren ins 1 #include <iostream> 2 #include <time.h> 3 #include <random> 4

c++叠代器失效

個人 錯誤 自身 開始 崩潰 引用 重新 [0 但是 1.首先從一到題目開始談說起叠代器失效。有時我們很自然並且自信地 用下面方法刪除vector元素: #include <iostream>#include <stdio.h>#include

c++單例模式

lsi 但是 desc 模式 單例模式 ron spl 希望 構造函數 1 本篇主要討論下多線程下的單例模式實現:   首先是 double check 實現方式: 這種模式可以滿足多線程環境下,只產生一個實例。 template<typename T>

C#out修飾符、ref修飾符、params修飾符的簡單介紹

c# 一個 邏輯 本地 style 逗號 註意 可變 修飾 一、out修飾符   1、調用一個帶有輸出參數的方法也需要使用out 修飾符,但是作為輸出變量傳遞的本地變量在將他們作為輸出變量傳遞前不需要賦值(因為調用後會改變或丟失),編譯器允 許你傳遞未分

C#Console

copy 註意 組合 ext col 下一個 src sys 轉換 Console.Write 表示向控制臺直接寫入字符串,不進行換行,可繼續接著前面的字符寫入。Console.WriteLine 表示向控制臺寫入字符串後換行。Console.Read 表示從控制臺讀取

Objective-C成魔路【8-訪問成員變量和屬性】

order 線程安全 ring 內容 時間 targe 簡化 音樂 blank 郝萌主傾心貢獻,尊重作者的勞動成果。請勿轉載。 假設文章對您有所幫助,歡迎給作者捐贈,支持郝萌主,捐贈數額任意,重在心意^_^ 我要捐贈: 點擊捐贈 Cocos2d-X源代碼

【轉】c#繼承

none 實現 void 運算符重載 調用方法 需要 strong 靜態 顯式 一.繼承的類型   在面向對象的編程中,有兩種截然不同繼承類型:實現繼承和接口繼承   1.實現繼承和接口繼承   *實現繼承:表示一個類型派生於基類型,它擁有該基類型的所有成員字段和函

【轉】C#集合

tab 並發集合 get spa style con 都在 src 字典  數組(http://www.cnblogs.com/afei-24/p/6738128.html)的大小是固定的。如果元素的個數是動態的,就應使用集合類。     列表(http://www.cn

C++運算符重載

cells pro 運算符重載 似的 width uri erl wrap height C++ Code 1234567891011121314151617181920212223242526272829303132333435363738394041424

C++ const的使用

過多 依然 設計 以及 改變 我們 成員函數 pil 類對象 在類中,有時候為了避免誤操作而修改了一些人們不希望被修改的數據,此時就必須借助const關鍵字加以限定了。借助const關鍵字可以定義const類型的成員變量、成員函數、常對象以及對象的常引用。 const成員變

C++中typename和class的區別

type .get true 能夠 class .... ray pla 依賴 在c++Template中很多地方都用到了typename與class這兩個關鍵字,而且好像可以替換,是不是這兩個關鍵字完全一樣呢? 相信學習C++的人對class這個關鍵字都非常明白,clas

簡述c#sealed 修飾符

tar com led 三方 new ram space 不能 繼承類 sealed 修飾符表示密封 用於類時,表示該類不能再被繼承,不能和 abstract 同時使用,因為這兩個修飾符在含義上互相排斥 用於方法和屬性時,表示該方法或屬性不能再被重寫,必須和 overrid

c# Enum--枚舉

namespace html images 基礎類型 tostring 作用 constant pla 枚舉類 枚舉 收藏的博文連接   枚舉類型聲明為一組相關的符號常數定義了一個類型名稱。枚舉用於“多項選擇”場合,就是程序運行時從編譯時已經設定的固定數目的“選擇”中做出

C++友元函數和友元類

res con 形參 display tle private 一點 second main 通過friend關鍵字,我們可以將不屬於當前類的一個函數在當前類中加以聲明,該函數便可以成為當前類的友元函數。#include<iostream>using namesp

修羅場第二天:C#面向對象基礎(下)

dog 主函數 div 接口 對象 blank 返回值 情況 抽象 ------------接(上)http://www.cnblogs.com/HoloSherry/p/7100795.html   抽象類     抽象類也可以實現多態,使用關鍵字abstract。那麽什

C++客戶消費積分管理系統

lib rec dig 一個 urn 申請 discount number ext 之前數據結構課程設計要求做這麽一個小程序,現在貼上源碼,來和大家進行交流學習,希望大家給出意見和建議 程序以鏈表為主要數據結構對客戶信息進行存儲,對身份證號碼判斷了位數及構成(前十七位為

c#初識結構(Struct)

cnblogs get 自己 相同 col 處理 color bsp 定義 C# 結構(Struct)   首先結構是值類型數據結構。它使得一個單一變量可以存儲各種數據類型的相關數據。struct 關鍵字用於創建結構。通俗說:結構就是一個可以包含不同數據類型的集合。它是一種