詳解c++中的trait與policy模板技術(shù)
概述
我們知道,類(lèi)有屬性(即數(shù)據(jù))和操作兩個(gè)方面。同樣模板也有自己的屬性(特別是模板參數(shù)類(lèi)型的一些具體特征,即trait)和算法策略(policy,即模板內(nèi)部的操作邏輯)。模板是對(duì)有共性的各種類(lèi)型進(jìn)行參數(shù)化后的一種通用代碼,但不同的具體類(lèi)型又可能會(huì)有一些差異,比如不同的類(lèi)型可能會(huì)有自己的不同特征和算法實(shí)現(xiàn)策略。
trait模板技術(shù)
當(dāng)在模板代碼中需要知道類(lèi)型參數(shù)T的某些特征(比如需要知道T是哪個(gè)具體類(lèi)型,是否有默認(rèn)構(gòu)造函數(shù),希望該類(lèi)型有合理的缺省值,如int型缺省值為0),我們可以聲明一個(gè)描述T的特征的trait<T>模板,然后對(duì)每種具體類(lèi)型(如int,char,用戶(hù)定義的類(lèi))特化trait<T>,在各特化版本中用typedef為該具體類(lèi)型(或者想映射成的其他類(lèi)型)定義統(tǒng)一的別名(比如AliT),根據(jù)需要還可指定合理的缺省值等。這樣在原來(lái)模板文件中#include這個(gè)trait<T>模板的文件,就可以在模板代碼中使用trait<T>::AliT來(lái)獲得T的具體特征。
比如我們要計(jì)算數(shù)組各個(gè)元素的累加和,由于數(shù)組元素可以是各種類(lèi)型,我們使用模板來(lái)實(shí)現(xiàn)它,這時(shí)有一個(gè)類(lèi)型參數(shù)T。但在算法代碼中,某些情況下又必須知道T的具體類(lèi)型特征,才能作出特殊的處理。例如對(duì)char型的數(shù)組元素累加如果最終返回的也是char型的話(huà),很可能越界,因?yàn)閏har只占8位,范圍很小。我們可以為T(mén)的trait創(chuàng)建一個(gè)模板AccumulationTraits。具體代碼如下:
//accum1.hpp:累加算法模板:實(shí)現(xiàn)為函數(shù)模板,引入了trait。用數(shù)組首部指針及尾部后面的一個(gè)指針作參數(shù)
#ifndef ACCUM_HPP
#define ACCUM_HPP
#include "accumtraits.hpp"
#include <iostream>
template<typename T>
inline typename AccumulationTraits<T>::AccT accum(T const* beg,T const* end){
//返回值類(lèi)型是要操作的元素類(lèi)型T的trait
typedef typename AccumulationTraits<T>::AccT AccT;
AccT total=AccumulationTraits<T>::zero(); //返回具體類(lèi)型的缺省值
while(beg!=end){ //作累加運(yùn)算
total+=*beg;
++beg;
}
return total; //返回累加的值
}
#endif
//accumtraits.hpp:累加算法模板的trait
#ifndef ACCUMTRAITS_HPP
#define ACCUMTRAITS_HPP
template<typename T>
class AccumulationTraits; //只有聲明
//各個(gè)特化的定義
template<>
class AccumulationTraits<char>{ //把具體類(lèi)型char映射到int,累加后就返回int
public:
typedef int AccT; //統(tǒng)一的類(lèi)型別名,表示返回類(lèi)型
static AccT zero(){ //關(guān)聯(lián)一個(gè)缺省值,是累加時(shí)的初始缺省值
return 0;
}
};
template<>
class AccumulationTraits<short>{ //把具體類(lèi)型short映射到累加后的返回類(lèi)型int
public:
typedef int AccT;
static AccT zero(){ //沒(méi)有直接在類(lèi)內(nèi)部定義static變量并提供缺省值,而是使用了函數(shù)
//因?yàn)轭?lèi)內(nèi)部只能對(duì)整型和枚舉類(lèi)型的static變量進(jìn)行初始化
//其他類(lèi)型的必須類(lèi)內(nèi)部聲明,在外部進(jìn)行初始化
return 0;
}
};
template<>
class AccumulationTraits<int>{
public:
typedef long AccT;
static AccT zero(){
return 0;
}
};
template<>
class AccumulationTraits<unsigned int>{
public:
typedef unsigned long AccT;
static AccT zero(){
return 0;
}
};
template<>
class AccumulationTraits<float>{
public:
typedef double AccT;
static AccT zero(){
return 0;
}
};
//...
#endif
//accum1test.cpp:使用累加算法的客戶(hù)端代碼
#include "accum1.hpp"
#include <iostream>
int main(){
int num[]={1,2,3,4,5}; //整型數(shù)組
std::cout<<"the average value of the integer values is "
<<accum(&num[0],&num[5])/5<<'/n'; //輸出平均值
char name[]="templates"; //創(chuàng)建字符值數(shù)組
int length=sizeof(name)-1;
//輸出平均的字符值,返回的是int型,不會(huì)越界
std::cout<<"the average value of the characters in /""
<<name<<"/" is "<<accum(&name[0],&name[length])/length<<'/n';
return 0;
}
注意trait模板本身只是一個(gè)聲明,并不提供定義,因?yàn)樗⒉恢绤?shù)T具體是什么類(lèi)型。trait的定義由針對(duì)各個(gè)具體類(lèi)型的特化來(lái)提供。trait依賴(lài)于原來(lái)模板的主參數(shù)T,因?yàn)樗硎镜氖荰的特征信息。這里使用函數(shù)zero()為每個(gè)具體類(lèi)型還關(guān)聯(lián)了一個(gè)缺省值,用來(lái)作為累加的初始值。為什么不直接關(guān)聯(lián)為靜態(tài)變量呢?比如static AccT const zero=0。這主要是因?yàn)樵陬?lèi)內(nèi)部只能對(duì)整型和枚舉類(lèi)型的static變量進(jìn)行初始化,其他類(lèi)型的必須在類(lèi)內(nèi)部聲明,在外部進(jìn)行初始化。這里對(duì)char型數(shù)組元素進(jìn)行累加時(shí),返回int型,這樣就避免了會(huì)產(chǎn)生越界的情況。
總結(jié)出trait模板技術(shù)的核心思想:把模板參數(shù)T的具體特征信息抽象成一個(gè)獨(dú)立的模板,通過(guò)特化為具體的類(lèi)型并為該類(lèi)型關(guān)聯(lián)統(tǒng)一的別名,我們就可以在模板中引用這個(gè)別名,以獲得T的具體特征信息。注意一個(gè)模板參數(shù)可能有多種特征,每一個(gè)trait都可以抽象成一個(gè)trait模板??梢?jiàn)這里特化是獲得具體差異行為的關(guān)鍵。由于在模板中類(lèi)型T是抽象的,不能獲得它的具體特征,我們通過(guò)對(duì)T的特征進(jìn)行抽離,并特化為具體的類(lèi)型,才能獲得類(lèi)型的具體特征。從這可以看出我們還有一種實(shí)現(xiàn)方案,那就是直接特化模板accum,即針對(duì)char型進(jìn)行一個(gè)特化來(lái)進(jìn)行累加。但這樣特化版本中又要重寫(xiě)基本模板中那些相同的代碼邏輯(比如進(jìn)行累加的while循環(huán)),而實(shí)際上我們需要特化的只是類(lèi)型的特征信息。
在設(shè)計(jì)層面上,特化與模板的意圖正好相反。模板是泛型代碼,代表各個(gè)類(lèi)型之間的共性,而特化則表示各個(gè)類(lèi)型之間的差異。我們可以結(jié)合多態(tài)來(lái)深刻地把握這些設(shè)計(jì)思想。從一般意義上講,polymorphism是指具有多種形態(tài)或行為,它能夠根據(jù)單一的標(biāo)記來(lái)關(guān)聯(lián)不同的特定行為??梢?jiàn)條件語(yǔ)句if/else也可以看作是一種多態(tài),它根據(jù)標(biāo)記的不同狀態(tài)值來(lái)選擇執(zhí)行不同的分支代碼(代表不同的行為)。多態(tài)在不同的程序設(shè)計(jì)范型有不同的表現(xiàn)。
(1)面向過(guò)程的程序設(shè)計(jì):多態(tài)通過(guò)條件語(yǔ)句if/else來(lái)實(shí)現(xiàn)。這樣多態(tài)其實(shí)成了最基本的程序邏輯結(jié)構(gòu)。我們知道順序語(yǔ)句和條件語(yǔ)句是最基本的邏輯結(jié)構(gòu),switch語(yǔ)句本身就是if/else的變體,循環(huán)語(yǔ)句相當(dāng)于有一個(gè)goto語(yǔ)句的if/else。這種多態(tài)可以稱(chēng)為OP多態(tài),它最大優(yōu)點(diǎn)就是效率高,只有一個(gè)跳轉(zhuǎn)語(yǔ)句,不需要額外的開(kāi)銷(xiāo)。最大缺點(diǎn)就難以擴(kuò)展,很難應(yīng)對(duì)變化。當(dāng)有新的行為時(shí),就要修改原來(lái)的代碼,在if/else中再增加一個(gè)分支,然后重新編譯代碼。它只是一種低層次的多態(tài),需要程序員人工增加代碼,判斷標(biāo)記的值。
(2)面向?qū)ο蟪绦蛟O(shè)計(jì):多態(tài)通過(guò)虛函數(shù)機(jī)制,用繼承的方式來(lái)實(shí)現(xiàn)。這里的設(shè)計(jì)思想就是抽離類(lèi)型之間的共性,把它們放在基類(lèi)中,而具體的差異性則放到子類(lèi)中。我們使用基類(lèi)指針或引用作為單一的標(biāo)記,它會(huì)自動(dòng)的綁定到子類(lèi)對(duì)象上,以獲得不同的行為。函數(shù)重載也可以看作是一種多態(tài),函數(shù)名作為單一的標(biāo)記,我們通過(guò)不同的參數(shù)類(lèi)型來(lái)調(diào)用不同的重載版本,從而獲得不同的多態(tài)行為。這種多態(tài)稱(chēng)為OO多態(tài),它的優(yōu)點(diǎn)就是自動(dòng)化,易擴(kuò)展,提高了復(fù)用程度。它不需要程序員人工干預(yù),因?yàn)閯?dòng)態(tài)綁定是自動(dòng)進(jìn)行的。當(dāng)需要新的行為時(shí),從基類(lèi)繼承一個(gè)新的子類(lèi)即可,不需要修改原來(lái)的代碼,系統(tǒng)易維護(hù),也易擴(kuò)展。缺點(diǎn)就是降低了效率,當(dāng)縱向的繼承體系比較深時(shí),要?jiǎng)?chuàng)建大量的對(duì)象,虛函數(shù)一般也很少能夠被內(nèi)聯(lián),這會(huì)使內(nèi)存使用量大幅增加。OO多態(tài)是一種高層次的多態(tài),耦合性比OP多態(tài)低,但縱向的繼承體系仍然有一定的耦合性。
(3)泛型程序設(shè)計(jì):多態(tài)通過(guò)模板來(lái)實(shí)現(xiàn)。這里的設(shè)計(jì)思想就是不需要抽離類(lèi)型之間的共性,而是直接對(duì)類(lèi)型進(jìn)行參數(shù)化,把它設(shè)計(jì)成模板,以表示共性。類(lèi)型之間的差異通過(guò)特化來(lái)實(shí)現(xiàn)。編譯器會(huì)根據(jù)類(lèi)型參數(shù)(相當(dāng)于單一的標(biāo)記)自動(dòng)決定是從模板產(chǎn)生實(shí)例,還是調(diào)用特化的實(shí)例。這種多態(tài)稱(chēng)為GP多態(tài),它是橫向的,代表共性的模板與代表差異性的特化在同一層次上,它們之間是相互獨(dú)立的,因此它的耦合性更低,性能也更好。由于GP本身也支持繼承和重載,因此可以看出它是一種更高層次的多態(tài),而用模板來(lái)做設(shè)計(jì)甚至比面向?qū)ο笤O(shè)計(jì)還強(qiáng)大,因?yàn)槟0灞旧硪仓С置嫦驅(qū)ο蟮睦^承機(jī)制,它在面向?qū)ο髮哟紊线€作了一層更高的抽象(對(duì)類(lèi)進(jìn)行抽象)。GP多態(tài)還具有更好的健壯性,因?yàn)樗诰幾g期就進(jìn)行檢查。當(dāng)然,GP代碼比較難調(diào)試,這主要由于 編譯器支持得不好。
用模板參數(shù)來(lái)傳遞多種trait
前面我們?cè)赼ccum中通過(guò)組合的方式使用它的trait模板。我們也可直接給accum模板增加一個(gè)模板參數(shù)用來(lái)傳遞trait類(lèi)型,并指定一個(gè)缺省實(shí)參為AccumulationTraits<T>,這樣可以適應(yīng)有多種trait的情況。由于函數(shù)模板并不能指定缺省模板實(shí)參(其實(shí)現(xiàn)在許多編譯器都支持這個(gè)非標(biāo)準(zhǔn)特性),我們把a(bǔ)ccum實(shí)現(xiàn)為一個(gè)類(lèi)模板。算法作為一個(gè)函數(shù)來(lái)使用時(shí)應(yīng)該會(huì)更自然一點(diǎn),因此可以再用一個(gè)函數(shù)模板來(lái)包裝這個(gè)類(lèi)模板,使之變成一個(gè)函數(shù)模板。如下:
//accum2.hpp:累加算法模板:實(shí)現(xiàn)為類(lèi)模板,用模板參數(shù)來(lái)傳遞trait
//可用一個(gè)內(nèi)聯(lián)函數(shù)模板作為包裝器來(lái)包裝這個(gè)類(lèi)模板實(shí)現(xiàn)
#ifndef ACCUM_HPP
#define ACCUM_HPP
#include "accumtraits.hpp"
template<typename T,typename AT=AccumulationTraits<T> >
class Accum{ //實(shí)現(xiàn)為類(lèi)模板,模板參數(shù)AT代表要使用的trait,并有一個(gè)缺省實(shí)參
public:
static typename AT::AccT accum(T const* beg,T const* end){
typename AT::AccT total=AT::zero(); //獲取缺省值
while(beg != end){ //進(jìn)行累加
total+=*beg;
++beg;
}
return total; //返回累加的值
}
};
//用內(nèi)聯(lián)的函數(shù)模板來(lái)包裝,對(duì)默認(rèn)的trait,使用一個(gè)獨(dú)立的重載版本
template<typename T>
inline typename AccumulationTraits<T>::AccT accum(T const* beg,T const* end){
return Accum<T>::accum(beg,end);
}
template<typename T,typename Traits>
inline
typename Traits::AccT accum(T const* beg,T const* end){
return Accum<T,Traits>::accum(beg,end);
}
#endif
使模板參數(shù)來(lái)傳遞trait的一個(gè)最大好處是當(dāng)有多種trait時(shí),我們可以為第2個(gè)模板參數(shù)指定需要的各種trait。這里還使用了所謂的內(nèi)聯(lián)包裝函數(shù)技術(shù)。當(dāng)我們實(shí)現(xiàn)了一個(gè)函數(shù)(模板),但接口比較難用時(shí),比如這里是類(lèi)模板,用戶(hù)即使是使用默認(rèn)的AccumumationTrait<T>,也要顯式指定第一個(gè)實(shí)參T,不好用。我們可以用一個(gè)包裝函數(shù)來(lái)包裝它,使其接口變得對(duì)用戶(hù)非常簡(jiǎn)單友好,為了避免包裝帶來(lái)的性能損失,要把包裝函數(shù)(模板)聲明為內(nèi)聯(lián),編譯器通常會(huì)直接調(diào)用位于內(nèi)聯(lián)函數(shù)里面的那個(gè)函數(shù)。這樣,使用默認(rèn)trait時(shí)客戶(hù)端代碼accum1test.cpp不需要做任何修改。
policy模板技術(shù)
與trait模板技術(shù)的思想類(lèi)似,只不過(guò)是對(duì)模板代碼中的算法策略進(jìn)行抽離。因?yàn)槟0宕a中對(duì)不同的具體類(lèi)型可能某一部分代碼邏輯(即算法策略)會(huì)不一樣(比如對(duì)int是累加,對(duì)char則是連接)。policy模板就代表了這些算法策略。它不需要使用特化,policy只需重新實(shí)現(xiàn)這個(gè)與原模板中的代碼不同的具體算法策略即可。
上面是對(duì)類(lèi)型的不同trait產(chǎn)生的差異。實(shí)際上對(duì)不同的trait,其算法策略(policy)也可能有不同的差異。比如我們對(duì)char型元素的數(shù)組,不用累加策略,而是用連接的策略。我們還可以把a(bǔ)ccum看作是一般的數(shù)組元素累積性函數(shù),既可以累加,也可以累乘、連接等。一種方法是我們可以直接對(duì)accum函數(shù)模板的不同具體類(lèi)型提供特化,重寫(xiě)各自的代碼邏輯。但實(shí)際上,這時(shí)我們需要變化的只有total+=*beg那一條語(yǔ)句,因此我們可以使用policy模板技術(shù),為模板的不同policy創(chuàng)建獨(dú)立的模板。這里我們把policy實(shí)現(xiàn)為具有一個(gè)成員函數(shù)模板的普通類(lèi)(當(dāng)然policy也可以直接實(shí)現(xiàn)為模板)。對(duì)累加策略為SumPolicy,對(duì)累乘策略為MultPolicy等。代碼如下:
//policies1.hpp:累加元素模板的不同policy實(shí)現(xiàn):實(shí)現(xiàn)為含有成員函數(shù)模板的普通類(lèi)
#ifndef POLICIES_HPP
#define POLICIES_HPP
class SumPolicy{ //累加的policy
public:
template<typename T1,typename T2>
static void accumulate(T1& total,T2 const& value){
total+=value; //作累加
}
};
class MultPolicy{ //累乘的policy
public:
template<typename T1,typename T2>
static void accumulate(T1& total,T2 const& value){
total*=value;
}
};
//其他各種policy
//......
#endif
引入了policy后,把累加算法實(shí)現(xiàn)為類(lèi)模板,如下:
//accum3.hpp:累加算法模板,引入了作為普通類(lèi)的policy,默認(rèn)是采用SumPolicy
#ifndef ACCUM_HPP
#define ACCUM_HPP
#include "accumtraits.hpp"
#include "policies1.hpp"
template<typename T,typename Policy=SumPolicy,typename Traits=AccumulationTraits<T> >
class Accum{ //累加算法實(shí)現(xiàn)為類(lèi)模板,默認(rèn)采用SumPolicy
public:
typedef typename Traits::AccT AccT;
static AccT accum(T const* beg,T const* end){
AccT total=Traits::zero(); //獲取缺省值
while(beg !=end){ //作累積運(yùn)算
Policy::accumulate(total,*beg); //使用給定的算法策略來(lái)進(jìn)行累積
++beg;
}
return total; //返回累積起來(lái)的值
}
};
#endif
當(dāng)policy為普通類(lèi)時(shí),這里用一個(gè)類(lèi)型模板參數(shù)來(lái)傳遞不同的policy,缺省的policy為SumPolicy。客戶(hù)端使用Accum<int>::accum(&num[0],&num[5])這樣的形式來(lái)對(duì)int型數(shù)組元素進(jìn)行累加。注意當(dāng)trait使用默認(rèn)的AccummulationTrait<T>時(shí),累乘策略MultPolicy實(shí)際上就不能用在這里了。因?yàn)槌跏贾禐?,那累乘的結(jié)果最終總是0,可見(jiàn)policy與trait是有聯(lián)系的。當(dāng)然我們也可以換一種方法來(lái)實(shí)現(xiàn),即直接讓accum函數(shù)增加一個(gè)形參T val,用val來(lái)指定運(yùn)算的初始值。實(shí)際上,C++標(biāo)準(zhǔn)庫(kù)函數(shù)accumulate()就是把這個(gè)初值作為第3個(gè)實(shí)參。
模板化的policy
上面的policy實(shí)現(xiàn)為具有一個(gè)成員函數(shù)模板的普通類(lèi),這可以看出,其實(shí)policy可以直接實(shí)現(xiàn)為一個(gè)模板。這時(shí)在accum算法中就要用模板模板參數(shù)來(lái)傳遞policy了。代碼如下:
//policies2.hpp:把各個(gè)policy實(shí)現(xiàn)為類(lèi)模板
#ifndef POLICIES_HPP
#define POLICIES_HPP
template<typename T1,typename T2>
class SumPolicy{
public:
static void accumulate(T1& total,T2 const& value){
total+=value;
}
};
//...
#endif
//accum4.hpp:累加算法模板,引入了作為類(lèi)模板的policy,默認(rèn)是采用SumPolicy
#ifndef ACCUM_HPP
#define ACCUM_HPP
#include "accumtraits.hpp"
#include "policies2.hpp"
template<typename T,
template<typename,typename> class Policy=SumPolicy,
typename Traits=AccumulationTraits<T> >
class Accum{ //累加算法實(shí)現(xiàn)為類(lèi)模板,默認(rèn)采用模板SumPolicy
public:
typedef typename Traits::AccT AccT; //獲取返回類(lèi)型,它是T的trait
static AccT accum(T const* beg,T const* end){
AccT total=Traits::zero(); //獲取缺省值
while(beg !=end){ //作累積運(yùn)算
Policy<AccT,T>::accumulate(total,*beg); //使用給定的算法策略來(lái)進(jìn)行累積
++beg;
}
return total; //返回累積起來(lái)的值
}
};
#endif
trait模板與policy模板技術(shù)的比較
(1)trait注重于類(lèi)型,policy更注重于行為。
(2)trait可以不通過(guò)模板參數(shù)來(lái)傳遞,它表示的類(lèi)型通常具有自然的缺省值(如int型為0),它依賴(lài)于一個(gè)或多個(gè)主參數(shù),它 一般用模板來(lái)實(shí)現(xiàn)。
(3)policy可以用普通類(lèi)來(lái)實(shí)現(xiàn),也可以用類(lèi)模板來(lái)實(shí)現(xiàn),一般通過(guò)模板參數(shù)來(lái)傳遞。它并不需要類(lèi)型有缺省值,缺省值通常是在policy中的成員函數(shù)中用一個(gè)獨(dú)立的參數(shù)來(lái)傳遞。它通常并不直接依賴(lài)于模板參數(shù)。
一般在模板中指定兩個(gè)模板參數(shù)來(lái)傳遞trait和policy。而policy的種類(lèi)更多,使用更頻繁,因此通常代表policy的模板參數(shù)在代表trait的模板參數(shù)前面。
標(biāo)準(zhǔn)庫(kù)中的std::iterator_traits<T>是一個(gè)trait,可通過(guò)iterator_traits<T>::value_ type來(lái)引用T表示的具體類(lèi)型。其實(shí)現(xiàn)也是用特化來(lái)獲取各個(gè)具體的類(lèi)型,有全局特化也有局部物化,如指針類(lèi)型,引用類(lèi)型等就只能通過(guò)局部特化為T(mén)*,T&來(lái)實(shí)現(xiàn)。
以上就是詳解c++中的trait與policy模板技術(shù)的詳細(xì)內(nèi)容,更多關(guān)于c++中的trait與policy模板技術(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++11, 14, 17對(duì)tuple元素的訪問(wèn)詳情
這篇文章主要介紹了C++11, 14, 17對(duì)tuple元素的訪問(wèn)詳情,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
C++ std::unique_lock 用法實(shí)例詳解
std::unique_lock 是 C++11 提供的一個(gè)用于管理互斥鎖的類(lèi),它提供了更靈活的鎖管理功能,適用于各種多線程場(chǎng)景,這篇文章給大家介紹了C++ std::unique_lock 用法,感興趣的朋友跟隨小編一起看看吧2023-09-09
C語(yǔ)言qsort函數(shù)用冒泡排序?qū)崿F(xiàn)過(guò)程詳解
qsort函數(shù)是由C語(yǔ)言提供的標(biāo)準(zhǔn)庫(kù)函數(shù), 它的實(shí)現(xiàn)思想是快速排序。這篇文章主要介紹了C語(yǔ)言中qsort函數(shù)用法及用冒泡排序?qū)崿F(xiàn)qsort函數(shù)功能,需要的可以參考一下2023-02-02
GCC 編譯使用動(dòng)態(tài)鏈接庫(kù)和靜態(tài)鏈接庫(kù)的方法
根據(jù)鏈接時(shí)期的不同,庫(kù)又有靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)之分,有別于靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)的鏈接是在程序執(zhí)行的時(shí)候被鏈接的2013-03-03
C++中std::chrono時(shí)間庫(kù)的全面解析
C++?std::chrono時(shí)間庫(kù)是C++標(biāo)準(zhǔn)庫(kù)提供的一個(gè)時(shí)間處理庫(kù),提供了一個(gè)方便、靈活和精確的時(shí)間處理工具,下面小編就帶大家深入了解一下std::chrono時(shí)間庫(kù)的使用吧2023-10-10
c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié)
這篇文章主要介紹了c++利用vector創(chuàng)建二維數(shù)組的幾種方法總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
VC6.0實(shí)現(xiàn)讀取Excel數(shù)據(jù)的方法
這篇文章主要介紹了VC6.0實(shí)現(xiàn)讀取Excel數(shù)據(jù)的方法,非常實(shí)用的功能,需要的朋友可以參考下2014-07-07

