九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
深入理解C++ SFINAE(匹配失敗不是錯(cuò)誤)

這個(gè)概念我也是最近才聽(tīng)說(shuō)到的,來(lái)源是《Extended STL, Volume 1: Collections and Iterators》,在其第13章。
SFINAE,即Substitution Failure Is Not an Error!可以理解為匹配失敗不是錯(cuò)誤,更嚴(yán)格的說(shuō)應(yīng)該是參數(shù)匹配失敗不是一個(gè)編譯時(shí)錯(cuò)誤。
光看這些解釋我想除了少部分C++專(zhuān)家之外基本上都會(huì)迷糊,當(dāng)然我不是專(zhuān)家,所以我迷糊了。
         本著不知道就Google的態(tài)度,我Google了,不過(guò)得到的資料并不多,在維基百科上面找到點(diǎn)資料但是看過(guò)之后并不是很明白。當(dāng)然,不明白不等于不去探索了,這有違我的行為準(zhǔn)則,后來(lái)我在其它的書(shū)上找到了類(lèi)似的東西,現(xiàn)在跟大家分享??催@樣的一段代碼:
#include <iostream>
using namespace std;
void print( int iNum ) {
         cout<<"int print( int )"<< endl;
}
template < typename _Ty >
void print( _Ty tt ){
           typename _Ty::value_type vt_someval;
           cout<<"template < typename _Ty >"<< endl;
}
int main()
 {
         short siNum = 10;
         print( siNum );-
        return 0;
}
        這段代碼能否通過(guò)編譯呢?實(shí)踐證明,這段代碼無(wú)法通過(guò)編譯,比如說(shuō)我在Visual Studio 2008 SP1下面的錯(cuò)誤:
1>e:\documents\visual studio 2008\projects\baidu\main.cpp(13) : error C2825: '_Ty': 當(dāng)后面跟“::”時(shí)必須為類(lèi)或命名空間
1> e:\documents\visual studio 2008\projects\baidu\main.cpp(20): 參見(jiàn)對(duì)正在編譯的函數(shù) 模板 實(shí)例化“void print<short>(_Ty)”的引用
1>         with
1>         [
1>             _Ty=short1>         ]
1>e:\documents\visual studio 2008\projects\baidu\main.cpp(13) : error C2039: “value_type”: 不是“`global namespace'”的成員
1>e:\documents\visual studio 2008\projects\baidu\main.cpp(13) : error C2146: 語(yǔ)法錯(cuò)誤 : 缺少“;”(在標(biāo)識(shí)符“vt_someval”的前面)
1>e:\documents\visual studio 2008\projects\baidu\main.cpp(13) : error C2065: “vt_someval”: 未聲明的標(biāo)識(shí)符
        如何解決這個(gè)編譯錯(cuò)誤呢?有很多方法,比如說(shuō)我們可以特化short類(lèi)型:
template <>
 void print<short>( short st )
{
         cout<<"short st"<<endl;
}
        實(shí)踐證明,這可以解決這個(gè)錯(cuò)誤,但是我們這里討論的是SFINAE??聪旅孢@段代碼:
#include <iostream>
using namespace std;
void print( int iNum )
{
         cout<<"int print( int )"<< endl;
}
template < typename _Ty >
 void print( _Ty tt, typename _Ty::value_type* pvt_dummy = NULL )
{
           typename _Ty::value_type vt_someval;
           cout<<"template < typename _Ty >"<< endl;
}

int main() {   
     short siNum = 10;
     print( siNum );-
     return 0;
}
        如果你的編譯器沒(méi)有問(wèn)題,那么這段程序是可以通過(guò)編譯的。為什么編譯器會(huì)放棄使用short去實(shí)例化print模板而選擇提升short為int去執(zhí)行第一個(gè)print呢?
         這個(gè)就是SFINAE,C++的一個(gè)特性。
         SFINAE最早由Daveed Vandevorde和Nicolai Josuttis提出,它意味著寧可對(duì)有問(wèn)題的類(lèi)型不考慮函數(shù)的重載也不要產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。如果這里參數(shù)的類(lèi)型中有一個(gè)value_type的嵌套類(lèi)型,那么它就是重載決議集合的一部分。
         有點(diǎn)暈?OMG,其實(shí)我也暈,換句話說(shuō):編譯器在辨認(rèn)函數(shù)模板時(shí),假如有一個(gè)特化會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤(即出現(xiàn)編譯失敗),只要還有別的選擇可以被選擇,那么就無(wú)視這個(gè)特化錯(cuò)誤而去選擇另外的可選選擇。比如下面這樣使用:
class Test {};
int main()
{
Test a;
print( a );
-return 0;
}  
      那么編譯器給出的錯(cuò)誤是:         error C2664: “print”: 不能將參數(shù) 1 從“Test”轉(zhuǎn)換為“int”, 而不是與模板特化相關(guān)的問(wèn)題。
      這是C++一個(gè)非常重要的特性,如果沒(méi)有這個(gè)特性會(huì)對(duì)早期的很多代碼造成破壞(因?yàn)楫?dāng)時(shí)沒(méi)有模板),而且還會(huì)產(chǎn)生很多難以理解的代碼。
         回過(guò)頭去看為什么把value_type作為參數(shù)的一部分或者是返回值編譯器就可以發(fā)覺(jué)我們提供的類(lèi)型不能適合語(yǔ)義而最初的代碼又不能發(fā)覺(jué)呢?這取決于模板實(shí)例化的過(guò)程,如果返回值和參數(shù)都可以匹配那么這個(gè)實(shí)例化就等同于成功了,此時(shí)此刻就表示編譯器已經(jīng)選擇了模板特化而不是其它選擇;當(dāng)約束位于參數(shù)或者是返回值的時(shí)候,模板參數(shù)匹配的適合就會(huì)失敗,這就產(chǎn)生了一個(gè)編譯時(shí)錯(cuò)誤,這個(gè)時(shí)候編譯器就會(huì)按照SFINAE原則去看是否還有其它選擇。
          得益于泛型編程和模板元編程的飛速發(fā)展,在boost庫(kù)的enable_if、mpl、type_traits中為我們提供了很多非常好的解決方案。如果有興趣的話可以看看這些書(shū)《C++模板元編程》(英文版:《C++.Template.Metaprogramming》)、《超越c++標(biāo)準(zhǔn)庫(kù)——boost程序庫(kù)導(dǎo)論》(英文版:《Beyond the C++ Standard Library: An Introduction to Boost》),當(dāng)然還有Boost的文檔。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C++11中的 “enable
std:forward 完美轉(zhuǎn)發(fā)
C++ 模板基礎(chǔ)談 - C/C++ / C++ 語(yǔ)言
C++11 標(biāo)準(zhǔn)新增特性
模板類(lèi)中定義std::list::iterator iter在Linux下不識(shí)別
C++ typename的起源與用法
更多類(lèi)似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服