日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

C++模板(template)中typename

發布時間:2023/12/15 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 C++模板(template)中typename 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、typename關鍵字

  在聲明template參數時, 前綴關鍵字class和typename可以互換,但在使用模板參數T的內部類型名稱即嵌套從屬名稱時只能用typename。

  在C++標準化的過程中,引入關鍵字typename是為了說明:模板類型參數內部的標識符(associated type,常見于STL中的各種容器)也可以是一個類型:

  比如:

template<typename T>
class MyClass
{
    typename T::SubType* ptr;
}

  這里介紹模板內參數名稱的幾個概念;

  從屬名稱(dependent names): 模板(template)內出現的名稱, 依賴于某個模板(template)參數, 如T t;

  嵌套從屬名稱(nested dependent names):從屬名稱在class內呈嵌套裝, 如T::const_iterator ci;

  非從屬名稱(non-dependent names): 不依賴任何template參數的名稱, 如int value;
  
  任何時候在模板(template)中指涉一個嵌套從屬類型名稱, 需要在前一個位置, 添加關鍵字typename;

  如果不特定指出typename, 嵌套從屬名稱, 有可能產生解析(parse)歧義,可能會報錯(GCC): error: need 'typename' before 'T::xxx' because 'T' is a dependent scope。

  比如:

template<typename T>
class MyClass
{
    /*typename*/ T::SubType* ptr;
}

  上述程序中,第二個typename被用來說明,SubType是定義與類T內部的一種類型,也就是associated type,因而,ptr是一個指向T::SubType類型的指針。如果不使用typename,T::SubType會被優先看做T的一個靜態成員,也就是一個具體而變量或對象,于是,下面的表達式:

T::SubType* ptr;

  編譯器此時就無法辨別這SubType是什么,因為SubType可能是模板參數T內的一個static變量,ptr可以看成一個全局變量,此時代碼會被看做類T的靜態成員SubType和ptr的乘積,或者SubType可能是一個typedef比如

class Class_T{
    typedef int SubType;
    ...
};

  那上面代碼轉化過來就是這樣:

int *x;

2、嵌套從屬名稱使用typename的幾個場景

  a、模板內出現的名稱如果依賴于某個模板參數,稱之為從屬名稱(dependent name)。如果從屬名稱在class內呈嵌套狀,我們稱為嵌套從屬名稱(nested dependent name),舉例如下:

template<typename T>
void print(const T & container)
{
    T::const_iterator iter(container.begin());
    cout << *iter << endl;
    int value = *iter;
    return;
}

在上述代碼中,iter 的類型是依賴于模板參數T的,因此被稱為 從屬名稱;
同理,value的類型是語言內置類型,不依賴于任何模板參數,因此被稱為 非從屬名稱;
C++編譯器在面對從屬名稱時,如果此時該從屬名稱又嵌套了其他類型,如此處的 iter就是T::const_iterator類型,這里的T::const_iterator 稱為嵌套從屬類型名稱(嵌套于T類型,從屬于模板參數T)

 或者

template<typename T> // typename allowed (as is "class")
void f(const T& container, // typename not allowed
        typename T::iterator iter); // typename required

  上述的T并不是嵌套從屬類型名稱 (它并非嵌套與任何“取決于模板參數”的東西內),所以聲明container時并不需要以typename為前導。

但T::iterator是個嵌套從屬類型名稱,所以必須以typename為前導。  

  b、某個模板類里面typedef類型時,如果這個類型與模板參數T相關,就需要使用typename。即這樣的形式:

template <class T>
class Test
{
public:
 typedef map<int, T> TEMPLATE_MAP; //TEMPLATE_MAP不需要typename,因為它不依賴其他的名稱
 typedef map<int, T>::iterator TEMPLATE_MAP_ITER;  //error! 嵌套從屬名稱,依賴其他類的iterator名稱
 typedef typename map<int, T>::iterator TEMPLATE_MAP_ITER; //yes 
};

  c、例外:嵌套從屬類型名稱, 如果是基類列表(base class list)和成員初值列(member initialization list)中,不使用typename;

/*
 * BInsertSort.cpp
 *
 *  Created on: 2014.4.17
 *      Author: Spike
 */
 
#include <iostream>
#include <vector>
 
using namespace std;
 
struct Number {
    Number(int x) {
        std::cout << "Number = " << x << std::endl;
    }
};
 
template<typename T>
struct Base{
    typedef Number Nested;
};
 
template<typename T>
class Derived: public Base<T>::Nested { //不用typename
public:
    explicit Derived(int x) : Base<T>::Nested(x) { //不用typename
        typename Base<T>::Nested temp(7); //必須使用
    }
};
 
int main () {
    Derived<int> d(5);
 
    return 0;
}

總結

以上是生活随笔為你收集整理的C++模板(template)中typename的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。