最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++元編程語言初步入門詳解

 更新時間:2021年10月21日 11:33:36   作者:微小冷  
這篇文章主要為大家介紹了C++元編程語言初步入門的詳解示例,文中包含詳細(xì)的基本概念及運用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助

模板

由于模板元編程需要以面向?qū)ο鬄榛A(chǔ),所以如有疑問之處可以先補充一點C++面向?qū)ο蟮闹R:

C++面向?qū)ο筮@一篇就夠了

泛型初步

由于C++是靜態(tài)強類型語言,所以變量一經(jīng)創(chuàng)建,則類型不得更改。如果我們希望創(chuàng)建一種應(yīng)用廣泛地復(fù)數(shù)類型,那么相應(yīng)地需要基于int、float、double這些基礎(chǔ)類型逐一創(chuàng)建,十分麻煩。泛型編程便是為了簡化這一過程而生。

能夠容納不同數(shù)據(jù)類型作為成員的類被成為模板類,其基本方法為在類聲明的上面加上一行模板聲明代碼

template<typename T>,下一行為class myClass,其調(diào)用過程為myClass<T> m。

列舉案例如下

#include<iostream>
using namespace std;
template<typename C>
struct Abstract{
    C real;         //real為C類型
    C im;
    Abstract(C inReal, C inIm){
        real = inReal;
        im = inIm;
    }
    void printVal(){
        cout<<"Abstract:"<<real<<"+"<<im<<"i"<<endl;
    };
    Abstract& multi(Abstract val){
        C temp = real*val.real - im*val.im;
        im = real*val.real + im*val.im;
        real = temp;
        return *this;
    };
};
int main(){
    Abstract<float> fTemp{1,2};//C類型為float
    fTemp.multi(fTemp);
    fTemp.printVal();
    system("pause");
    return 0;
}

函數(shù)模板

當(dāng)然,上述multi并不能實現(xiàn)兩個不同類型的Abstract之間的相乘,所以可以將multi函數(shù)改為

    template<typename T>
    Abstract<C>& multi(Abstract<T> val){
        C temp = real*val.real - im*val.im;
        im = real*val.real + im*val.im;
        real = temp;
        return *this;
    }

這樣就能夠?qū)崿F(xiàn)如下功能。

int main(){
    Abstract<float> fTemp{1,2};
    Abstract<int> iTemp{1,2};
    fTemp.multi(iTemp);
    fTemp.printVal();
    getReal(fTemp);
    system("pause");
    return 0;
}

友元

模板類具備一部分普通類的性質(zhì),比如struct和class的區(qū)別,public、protected、private的性質(zhì),以及友元等。模板的聲明特性也可以應(yīng)用在函數(shù)中,例如

#include<iostream>
using namespace std;
template<typename C>
class Abstract{
    C real;
    C im;
public:
    Abstract(C inReal, C inIm){
        real = inReal;
        im = inIm;
    }
    void printVal(){
        cout<<"Abstract:"<<real<<"+"<<im<<"i"<<endl;
    };
    Abstract& multi(Abstract val){
        C temp = real*val.real - im*val.im;
        im = real*val.real + im*val.im;
        real = temp;
        return *this;
    }
    template<typename T> friend void getReal(Abstract<T> num);  //聲明友元
};
template<typename C>
void getReal(Abstract<C> num){
    cout<<num.real<<endl;
}
int main(){
    Abstract<float> fTemp{1,2};
    fTemp.multi(fTemp);
    fTemp.printVal();
    getReal(fTemp);
    system("pause");
    return 0;
}

需要注意的一點是,在模板類中聲明友元,其前綴<typename T>中的類型標(biāo)識不得與已有的類型標(biāo)識重復(fù),否則編譯無法通過。

由于函數(shù)模板可以針對不同的數(shù)據(jù)類型進(jìn)行求解操作,是對函數(shù)或者方法實例的抽象,所以又被稱為算法。

模板參數(shù)

如果將模板理解為一種類型聲明的函數(shù),那么模板也應(yīng)該具備一些函數(shù)具備的功能。首先其模板參數(shù)中可以包含實際類型參數(shù),例如

template<typename T, int max>
class Test{}

其調(diào)用時可以寫為

Test<int,256> pixel;

模板同樣支持默認(rèn)參數(shù),即可以實現(xiàn)如下形式

template<typename T=int, int max=256>
class Test{}
Test pixle;

除了數(shù)據(jù)類型、值之外,模板本身也可以作為模板參數(shù),例如下面的形式是合法的。

template<typename T, template<typename> class C>
struct Test{
    C<T>* val;
    Test(C<T>* inVal){
        val = inVal;
    }
};
int main(){
    Abstract<int> fTemp{1,2};
    Test<int,Abstract> test(&fTemp);
    test.val->printVal();
    system("pause");
    return 0;
}

其結(jié)果為

PS E:\Code\cpp> g++ .\generic.cpp
PS E:\Code\cpp> .\a.exe
Abstract:1+2i
請按任意鍵繼續(xù). . . 

需要注意的一點是,在模板類中定義的模板類,需要進(jìn)行實例化,否則會出現(xiàn)錯誤,所以在Test中,以指針形式創(chuàng)建了模板類。

類型函數(shù)

以數(shù)據(jù)類型為輸入或輸出的函數(shù)即為類型函數(shù),在C語言中,sizeof便是一種類型函數(shù),其輸入為數(shù)據(jù)類型,輸出為數(shù)據(jù)類型所需要的內(nèi)存空間。

在C++11中,using可以實現(xiàn)數(shù)據(jù)類型賦予的功能,其使用方法與typedef相似

template<typename T>
struct Test{
    using type = T;
}

元編程的基本概念

元編程是泛型編程的一個超集,兩者的本質(zhì)均是針對不同數(shù)據(jù)類型的算法,后者則更關(guān)注傳入?yún)?shù)的廣泛性。如果將元編程分為四個層次

  • 無計算
  • 運算符連接的運算
  • 編譯時具備選擇等非遞歸計算
  • 編譯時具備遞歸運算

那么泛型編程可以作為第一類元編程,或者說更加關(guān)注的是參數(shù)的傳入傳出過程,而元編程則更關(guān)注不同數(shù)據(jù)類型的選擇過程。

例如,我們可以實現(xiàn)一個最多包含三個元素的元組Tuple,其思路為,三元元素可以看成是一個二元元組與一個參數(shù)的組合;二元元組可以看成是一元元組與參數(shù)的組合;一元元組則是一個基本數(shù)據(jù)類型的變量。在這個元組的實現(xiàn)過程中,除了賦值過程實現(xiàn)泛型之外,也需要判斷當(dāng)前所實現(xiàn)的元組元素個數(shù),如果其初始化參量為3個時,需要遞歸式地創(chuàng)建變量,直到賦值參數(shù)為1個。則其實現(xiàn)如下

class Nil{};
//主模板
template<typename T1=Nil, typename T2=Nil, typename T3=Nil>
struct Tuple : Tuple<T2,T3>{
    T1 x;
    using Base = Tuple<T2,T3>;      //三元元組以二元元組為基礎(chǔ)
    //返回值為Tuple<T2,T3>指針類型的base()函數(shù)
    //static_cast將this轉(zhuǎn)化為Base*類型
    Base* base(){return static_cast<Base*>(this);}
    const Base* base() const {return static_cast<const Base*>(this);}
    //構(gòu)造函數(shù)繼承二元元組,在構(gòu)造本類中x的同時,構(gòu)造基類Tuple<T2,T3>
    Tuple(const T1& t1, const T2& t2, const T3& t3)
        :Base{t2,t3},x{t1}{}
};
template<typename T1>
struct Tuple<T1>{
    T1 x;
};
template<typename T1, typename T2>
struct Tuple<T1,T2> : Tuple<T2>{
    T1 x;
    using Base = Tuple<T2>;
    Base* base(){return static_cast<const Base*>(this);}
    const Base* base() const {return static_cast<const Base*>(this);}
    Tuple(const T1& t1,const T2& t2):Base{t2}, x{t1}{}
};
template<typename T1, typename T2, typename T3>
void print_elements(ostream& os, const Tuple<T1,T2,T3>& t){
    os<<t.x<<",";
    print_elements(os,*t.base());
}
template<typename T1, typename T2>
void print_elements(ostream& os, const Tuple<T1,T2>& t){
    os<<t.x<<",";
    print_elements(os,*t.base());
}
template<typename T1>
void print_elements(ostream& os, const Tuple<T1>& t){
    os<<t.x;
}
//運算符重載
template<typename T1, typename T2, typename T3>
ostream& operator<<(ostream& os, const Tuple<T1,T2,T3>& t){
    os<<"{";
    print_elements(os,t);
    os<<"}";
    return os;
}
int main(){
    Tuple<int,double,char> x{1,2.5,'a'};
    cout<<x<<endl;
    system("pause");
    return 0;
}

其輸出結(jié)果為

PS E:\Code\cpp> g++ .\generic.cpp
PS E:\Code\cpp> .\a.exe
{1,2.5,a}

可變參數(shù)模板

上述實現(xiàn)過程非常繁瑣,而且限制了元組中的元素個數(shù),如果標(biāo)準(zhǔn)庫中用上述的書寫風(fēng)格,那么標(biāo)準(zhǔn)庫除了這個元組之外也寫不了其他的東西了。好在C++模板提供了可變參數(shù)的功能,例如,我們可以先將打印模板函數(shù)寫為

//typename... T 代表可變參數(shù)
template<typename T1, typename... T>
void print_elements(ostream& os, const Tuple<T1,T...>& t){
    os<<t.x<<",";
    print_elements(os,*t.base());
}
template<typename T1>
void print_elements(ostream& os, const Tuple<T1>& t){
    os<<t.x;
}
template<typename... T>
ostream& operator<<(ostream& os, const Tuple<T...>& t){
    os<<"{";
    print_elements(os,t);
    os<<"}";
    return os;
}

其輸出結(jié)果為

PS E:\Code\cpp> g++ .\generic.cpp
PS E:\Code\cpp> .\a.exe
{1,2.5,a}
請按任意鍵繼續(xù). . . 

然后將Tuple也做相同的更改

template<typename T1, typename... T>
struct Tuple : Tuple<T...>{
    T1 x;
    using Base = Tuple<T...>;      //N+1元元組以N元元組為基
    Base* base(){return static_cast<Base*>(this);}
    const Base* base() const {return static_cast<const Base*>(this);}
    //注意T&...的書寫格式
    Tuple(const T1& t1, const T&... t):Base{t...},x{t1}{}
};
template<typename T>
struct Tuple<T>{
    T x;
};
/*
    print模板
*/
int main(){
    Tuple<string, double,int,char> tt("hello",1.5,1,'a');
    cout<<tt<<endl;
    system("pause");
    return 0;
}

其輸出結(jié)果為

PS E:\Code\cpp> g++ .\generic.cpp
PS E:\Code\cpp> .\a.exe
{hello,1.5,1,a}

以上就是C++元編程語言初步入門詳解的詳細(xì)內(nèi)容,更多關(guān)于C++元編程語言初步的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言數(shù)據(jù)結(jié)構(gòu)二叉樹之堆的實現(xiàn)和堆排序詳解

    C語言數(shù)據(jù)結(jié)構(gòu)二叉樹之堆的實現(xiàn)和堆排序詳解

    堆是計算機科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱,通常是一個可以被看做一棵完全二叉樹的數(shù)組對象。而堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計的一種排序算法。本文將詳細(xì)介紹堆的實現(xiàn)和堆排序,需要的可以參考一下
    2022-04-04
  • C語言函數(shù)棧幀的創(chuàng)建與銷毀詳解

    C語言函數(shù)棧幀的創(chuàng)建與銷毀詳解

    函數(shù)棧幀(stack frame)就是函數(shù)調(diào)用過程中在程序的調(diào)用棧(call stack)所開辟的空間,下面這篇文章主要給大家介紹了關(guān)于C語言函數(shù)棧幀的創(chuàng)建與銷毀的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • C++計算圓形、矩形和三角形的面積

    C++計算圓形、矩形和三角形的面積

    這篇文章介紹了C++計算圓形、矩形和三角形面積的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • C/C++實現(xiàn)枚舉網(wǎng)上鄰居信息的示例詳解

    C/C++實現(xiàn)枚舉網(wǎng)上鄰居信息的示例詳解

    在Windows系統(tǒng)中,通過網(wǎng)絡(luò)鄰居可以方便地查看本地網(wǎng)絡(luò)中的共享資源和計算機,本文將介紹一個簡單的C++程序,使用Windows API枚舉網(wǎng)絡(luò)鄰居信息,并獲取對端名稱、本機名稱、主機名稱以及主機IP等信息,文中通過代碼示例給大家講解非詳細(xì),需要的朋友可以參考下
    2023-12-12
  • C語言中的字符型數(shù)據(jù)與ASCII碼表

    C語言中的字符型數(shù)據(jù)與ASCII碼表

    這篇文章主要介紹了C語言中的字符型數(shù)據(jù)與ASCII碼表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C語言中字符串處理函數(shù)sscanf的用法

    C語言中字符串處理函數(shù)sscanf的用法

    一直對于一些日期字符串中數(shù)字的提取比較頭疼,現(xiàn)看到 sscanf 對于字符串中的內(nèi)容提取較方便,本文主要介紹了C語言中字符串處理函數(shù)sscanf的用法,具有一定參考價值,感興趣的可以了解一下
    2023-08-08
  • 一文詳解如何在VS?Code上搭建C/C++開發(fā)環(huán)境

    一文詳解如何在VS?Code上搭建C/C++開發(fā)環(huán)境

    VSCode是由微軟開發(fā)的一款免費、開源、跨平臺的文本編輯器,它具有許多強大的功能,這篇文章主要給大家介紹了關(guān)于如何在VS?Code上搭建C/C++開發(fā)環(huán)境的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • C語言算法積累加tag的循環(huán)隊列

    C語言算法積累加tag的循環(huán)隊列

    這篇文章主要為大家介紹了C語言算法積累加tag的循環(huán)隊列的解題思路,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • break的使用for循環(huán)嵌套示例

    break的使用for循環(huán)嵌套示例

    這篇文章主要介紹了break的使用for循環(huán)嵌套示例,需要的朋友可以參考下
    2014-02-02
  • 函數(shù)外初始化與函數(shù)內(nèi)初始化詳細(xì)解析

    函數(shù)外初始化與函數(shù)內(nèi)初始化詳細(xì)解析

    函數(shù)內(nèi)初始化:bool FillStr(char *&szDst, int nSize);第一個參數(shù)中的&一定不能少,這是因為在函數(shù)外部我們只聲明了這個指針,具體這個指針指向內(nèi)存中的哪個地址我們并不知道,所以&是為了說明傳遞的是這個指針的引用,那么在函數(shù)內(nèi)初始化后這個指針的地址也就是外面指針的地址了
    2013-09-09

最新評論

双牌县| 澄城县| 桃园市| 江永县| 台山市| 大方县| 株洲县| 安图县| 永定县| 阳城县| 洪雅县| 伊金霍洛旗| 莒南县| 公安县| 博罗县| 玉龙| 仲巴县| 郑州市| 清苑县| 泸水县| 扬中市| 平泉县| 建始县| 文山县| 山东| 岳西县| 东宁县| 禹城市| 新兴县| 涞水县| 东丰县| 武川县| 赣榆县| 道孚县| 榆树市| 西城区| 方山县| 格尔木市| 都昌县| 舞阳县| 淅川县|