精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

我和編譯器的深夜對話:關于 C++ SFINAE 的那些事

開發
SFINAE(Substitution Failure Is Not An Error)是C++模板編程的核心技術之一,掌握了SFINAE,你就掌握了C++模板元編程的一把利器!

凌晨2點,又是一個和Bug搏斗的夜晚...

我:編譯器大哥,又見面了...

編譯器:喲,小老弟,又熬夜寫代碼啊?這次又遇到什么問題了?

我:別提了,我想寫個函數模板,能根據類型自動選擇不同的實現,結果一編譯就報錯...

template<typename T>
void process(T value) {
    value.foo();  // 如果T有foo方法就調用
    // 如果沒有foo方法就做別的事
}

編譯器:停停停!你這樣寫我怎么編譯?如果傳進來的類型沒有foo方法,我直接給你報錯好吧!

我:那怎么辦啊?我就想要個"有就調用,沒有就算了"的效果...

編譯器:這就要用到SFINAE了,小老弟。

我:SFINAE?這是啥?

編譯器:全稱是"Substitution Failure Is Not An Error",翻譯過來就是"替換失敗不是錯誤"。聽起來很高大上對吧?

我:emmm...能說人話嗎?

編譯器:?? 簡單說就是,當我嘗試用某個類型去匹配模板時,如果替換失敗了,我不會直接報錯,而是會去找其他可能的匹配。

我:還是不太懂...給個例子?

編譯器:行,看這個:

#include <iostream>
#include <type_traits>

// 第一個版本:給有foo方法的類型用
template<typename T>
auto process(T& value, int) -> decltype(value.foo(), void()) {
    std::cout << "調用了foo方法\n";
    value.foo();
}

// 第二個版本:給沒有foo方法的類型用
template<typename T>
void process(T& value, long) {
    std::cout << "沒有 foo() 方法,做別的事\n";
    // 做別的事情
}

我:哇!這個decltype(value.foo(), void())是什么鬼?還有為什么一個用int一個用long?

編譯器:這就是SFINAE的精髓!我來解釋一下:

decltype(value.foo(), void()):這里用了逗號表達式,返回類型是void()

如果T有foo方法,這個表達式就能正常計算,函數匹配成功

如果T沒有foo方法,value.foo()就會失敗,但我不報錯!我會去找其他重載

我:那int和long參數是干什么的?

編譯器:這是個小技巧!當你調用process(obj, 0)時:

  • 如果第一個版本(有int參數)匹配成功,就選它(因為0匹配int更精確)
  • 如果第一個版本失敗了,就會選第二個版本(0也能轉換成long)
  • 這樣就實現了優先級控制!

我:讓我試試!

struct HasFoo {
    void foo() { std::cout << "HasFoo::foo()\n"; }
};

struct NoFoo {
    void bar() { std::cout << "NoFoo::bar()\n"; }
};

int main() {
    HasFoo h;
    NoFoo n;
    
    process(h, 0);  // 會調用第一個版本
    process(n, 0);  // 會調用第二個版本
    return0;
}

編譯器:完美!注意調用時要傳入0作為第二個參數,這樣就實現了根據類型特性自動選擇不同實現。

我:哇塞!真的編譯通過了!但是這個寫法看起來好古老啊...

編譯器:哈哈,你說得對。現在有更現代的寫法,用std::enable_if:

#include <type_traits>

// 檢測是否有foo方法的工具
template<typename T>
class has_foo {
private:
    template<typename U>
    static auto test(int) -> decltype(std::declval<U>().foo(), std::true_type{});
    
    template<typename>
    static std::false_type test(...);
    
public:
    staticconstexprbool value = decltype(test<T>(0))::value;
};

// 有foo方法的版本
template<typename T>
std::enable_if_t<has_foo<T>::value> process(T value) {
    std::cout << "調用了foo方法\n";
    value.foo();
}

// 沒有foo方法的版本
template<typename T>
std::enable_if_t<!has_foo<T>::value> process(T value) {
    std::cout << "沒有foo方法,執行默認操作\n";
}

我:我去...這個has_foo是在干什么?

編譯器:這是個類型檢測器!它會在編譯期檢查類型T是否有foo方法:

  • test<U>(int)版本:如果U有foo方法,就返回std::true_type
  • test(...)版本:兜底版本,返回std::false_type
  • has_foo<T>::value就能得到布爾值結果

我:然后std::enable_if_t根據這個布爾值來啟用或禁用函數模板?

編譯器:聰明!std::enable_if_t<true>等于void,函數正常;std::enable_if_t<false>會導致替換失敗,觸發SFINAE,去找其他重載。

我:等等,還有更簡單的寫法嗎?這個has_foo寫起來好復雜...

編譯器:C++17開始有if constexpr,C++20有Concepts,但SFINAE的核心思想是一樣的。不過既然你問了,我給你看個C++20的版本:

#include <concepts>

template<typename T>
concept HasFoo = requires(T t) {
    t.foo();
};

template<HasFoo T>
void process(T value) {
    std::cout << "調用了foo方法\n";
    value.foo();
}

template<typename T>
void process(T value) requires (!HasFoo<T>) {
    std::cout << "沒有foo方法,執行默認操作\n";
}

我:哇!這個Concepts看起來清爽多了!

編譯器:對吧!但是理解了SFINAE,你才能真正理解這些新特性的原理。SFINAE可是C++模板編程的基石!

我:那SFINAE還有其他用途嗎?

編譯器:多了去了!比如:

1. 檢測成員函數

// 檢測是否有begin()方法(判斷是否可迭代)
template<typename T>
auto is_iterable(T t) -> decltype(t.begin(), t.end(), std::true_type{});

std::false_type is_iterable(...);

2. 檢測操作符重載

// 檢測是否支持+操作
template<typename T, typename U>
auto can_add(T t, U u) -> decltype(t + u, std::true_type{});

std::false_type can_add(...);

3. 函數重載決議

// 針對不同數值類型的特化處理
template<typename T>
std::enable_if_t<std::is_integral_v<T>> process_number(T value) {
    std::cout << "處理整數: " << value << "\n";
}

template<typename T>
std::enable_if_t<std::is_floating_point_v<T>> process_number(T value) {
    std::cout << "處理浮點數: " << value << "\n";
}

我:原來SFINAE這么強大!但是為什么叫"替換失敗不是錯誤"呢?

編譯器:因為在沒有SFINAE之前,模板參數替換失敗就會直接編譯錯誤。有了SFINAE,我會把失敗的候選從重載集合中刪除,繼續嘗試其他候選。只有所有候選都失敗了,才報錯。

我:所以SFINAE讓模板編程更靈活了?

編譯器:沒錯!它讓你能寫出真正泛型的代碼,根據類型特性自動適配。這就是C++模板元編程的魅力所在!

我:等等,我想到一個問題。如果兩個重載都能匹配怎么辦?

編譯器:好問題!這時候就看重載決議的優先級了:

  • 精確匹配 > 類型轉換
  • 非模板函數 > 模板函數
  • 特化模板 > 通用模板
  • 參數匹配度高的 > 參數匹配度低的

我:明白了!最后一個問題,SFINAE有什么坑需要注意的嗎?

編譯器:哈哈,當然有!

1. 只在函數簽名中生效

template<typename T>
void bad_sfinae(T value) {
    // 這里的錯誤不會觸發SFINAE,直接編譯錯誤!
    static_assert(sizeof(T) > 100);
}

2. 嵌套模板的陷阱

template<typename T>
struct Wrapper {
    // 這里的SFINAE可能不會按你預期工作
    template<typename U = T>
    std::enable_if_t<std::is_integral_v<U>> func();
};

3. 調試困難

SFINAE錯誤信息通常很難讀懂,建議多用static_assert輔助調試。

我:受教了!編譯器大哥,今天學到了很多!

編譯器:不客氣!記住,SFINAE不是魔法,它只是利用了C++的重載決議規則。多練習,多思考,你很快就能成為模板編程高手!

我:好的!那我去試試用SFINAE重構我的代碼了!

編譯器:去吧,少年!記住:代碼千萬行,類型安全第一行。編譯不規范,同事兩行淚!

總結

SFINAE(Substitution Failure Is Not An Error)是C++模板編程的核心技術之一:

核心思想:模板參數替換失敗時不報錯,而是嘗試其他重載

常用場景:類型檢測、條件編譯、函數重載

現代替代:C++17的if constexpr、C++20的Concepts

注意事項:只在函數簽名中生效,調試相對困難

掌握了SFINAE,你就掌握了C++模板元編程的一把利器!

編譯器:對了,小老弟,你這么愛學習,肯定還想了解更多C++后臺開發的干貨吧?

我:那必須的啊!還有什么好的學習資源推薦嗎?

編譯器:我聽說有個叫"跟著小康學編程"的公眾號挺不錯的,專門分享Linux C/C++后臺開發的技術,而且還有技術交流群可以加入。

我:真的嗎?那我得去關注一下!正好最近在學后臺開發,需要找個靠譜的地方交流學習。

編譯器:嗯,聽說群里的小伙伴都很活躍,經常分享一些實戰經驗和踩坑心得。畢竟一個人悶頭學習容易走彎路,有個技術圈子還是很重要的!

我:說得對!那我現在就去關注"跟著小康學編程",順便進群交流去了~

編譯器:去吧去吧!記住,學習路上不孤單,大家一起進步才是王道!??

責任編輯:趙寧寧 來源: 跟著小康學編程
相關推薦

2010-10-20 13:43:37

C++編譯器

2010-01-12 16:42:59

C++編譯器

2010-01-21 09:11:38

C++編譯器

2010-01-18 10:34:21

C++編譯器

2010-01-18 10:28:15

C++編譯器

2010-01-27 14:48:55

優秀C++編譯器

2010-01-08 16:00:46

C++編譯器

2014-03-03 10:00:53

編譯器集成開發環境

2010-01-14 15:29:44

C++編譯器

2010-02-03 13:14:03

C++編譯器命令

2013-03-18 09:42:47

C++C++ 11

2014-03-06 09:18:48

C++CIDE

2023-12-07 19:19:21

C++模板代碼

2015-03-23 10:04:43

c++編譯器c++實現原理總結

2021-03-07 16:31:35

Java編譯反編譯

2023-11-15 17:58:58

C++代碼

2017-08-29 09:30:01

編譯器LLVM編程語言

2010-01-21 09:26:53

CC++編譯器

2015-08-14 09:49:25

u3dc#

2010-01-27 13:53:40

強大的CC++編譯器
點贊
收藏

51CTO技術棧公眾號

天天天天天天天天操| 亚洲精品性视频| 阿v免费在线观看| 精品无码三级在线观看视频| 欧美成年人视频网站| 91丝袜在线观看| 精品国产黄a∨片高清在线| 亚洲人成电影网站色mp4| 国产在线精品一区二区中文| 中文天堂在线资源| 在线不卡亚洲| 色噜噜国产精品视频一区二区| 日本黄色一级网站| h1515四虎成人| 亚洲第一激情av| 亚洲激情电影在线| 五月婷婷六月色| 国产精品中文有码| 81精品国产乱码久久久久久| 国产又色又爽又高潮免费| 成人在线超碰| 在线播放中文一区| 青青在线视频观看| 黄色视屏在线免费观看| 亚洲色图19p| 色噜噜狠狠色综合网| 四虎永久在线精品免费网址| 精品一区二区三区久久| 国产成人jvid在线播放| 国产香蕉在线视频| 一区二区三区午夜探花| 国产亚洲精品久久| 18禁裸乳无遮挡啪啪无码免费| 国产一区二区三区免费观看在线| 色偷偷久久人人79超碰人人澡| 成人小视频在线观看免费| 中文日本在线观看| 欧美韩日一区二区三区| 久久精品五月婷婷| 天堂中文在线观看视频| 久久se精品一区二区| 国产精品福利在线| 激情视频网站在线观看| 一区二区福利| 性欧美xxxx| 国产精品suv一区二区| 伊人久久大香线蕉综合四虎小说| 色播久久人人爽人人爽人人片视av| 午夜理伦三级做爰电影| 日韩母乳在线| 日韩成人av网| 日本aaa视频| 亚洲人成网站77777在线观看| 精品奇米国产一区二区三区| 国产人妻精品久久久久野外| 亚洲精品一区av| 欧美福利视频导航| 樱花草www在线| 精品视频在线观看网站| 日韩一区二区中文字幕| 初高中福利视频网站| 国内精品视频| 精品国产乱码久久久久久夜甘婷婷 | 成人激情在线播放| av网站在线免费看| 成人手机电影网| 精品国产91亚洲一区二区三区www| 亚洲女人18毛片水真多| av一区二区三区黑人| 久久久久无码国产精品一区| 国模吧精品人体gogo| 亚洲国产精品国自产拍av| 亚洲精品自在在线观看| 精品51国产黑色丝袜高跟鞋| 亚洲精品免费视频| 精品欧美一区免费观看α√| www.成人爱| 欧美色视频一区| 一级黄色免费毛片| 久久视频在线观看| 一区二区三区高清国产| 国产一二三四区| 一区二区国产精品| 国产美女久久精品| 亚洲精品国偷拍自产在线观看蜜桃| 成人精品国产福利| 日韩尤物视频| 色呦呦久久久| 欧美亚洲动漫另类| 一级全黄裸体片| 久久最新网址| 欧美大片免费观看| 无码人妻精品一区二区50| 久草精品在线观看| 黄色99视频| 成人日日夜夜| 欧美视频不卡中文| 污免费在线观看| 国产精品亚洲二区| 久久6免费高清热精品| 久久久久久久久久成人| 国产精品456| 亚洲狠狠婷婷综合久久久| 国产99re66在线视频| 欧美三级电影一区| 国产男女猛烈无遮挡a片漫画| 久久影视一区| 欧美在线激情网| 性生活免费网站| 国产精品色呦呦| 免费看又黄又无码的网站| 久久天天久久| 亚洲人成电影在线播放| 国产亚洲欧美久久久久| 久久国产麻豆精品| 免费av在线一区二区| 国产蜜臀在线| 欧美一区日韩一区| 国产精成人品免费观看| 亚洲电影在线| 亚洲最大成人免费视频| yiren22亚洲综合伊人22| 婷婷中文字幕一区三区| 91视频福利网| 国产精品久久久久无码av| 青青精品视频播放| 黄色av网站免费在线观看| 国产精品久久久久久久久免费相片| 欧美亚洲精品一区二区| 中文字幕亚洲在线观看| 美女av一区二区| 国产又粗又大又爽视频| 国产欧美日韩综合精品一区二区| 2022亚洲天堂| 日本亚洲不卡| 91精品国产成人| 熟妇高潮一区二区三区| 亚洲午夜日本在线观看| 337p日本欧洲亚洲大胆张筱雨| 国产精品国产一区| 国产噜噜噜噜久久久久久久久| 成年午夜在线| 欧美日韩精品一区二区三区| 国产精品美女高潮无套| 视频一区二区三区入口| 日韩精品久久一区二区三区| 这里有精品可以观看| 国产视频精品久久久| 国产成人在线视频观看| 91亚洲精品乱码久久久久久蜜桃| 欧美午夜性视频| 农村少妇一区二区三区四区五区| 国语自产精品视频在免费| 国产综合在线播放| 精品人伦一区二区三区蜜桃免费 | 999免费视频| 国产精品久久久久一区二区三区共| 久久久国产欧美| 欧美岛国激情| 亚洲综合国产精品| www在线看| 亚洲精品小视频在线观看| 亚洲成人第一网站| 国产精品久久影院| 色婷婷综合在线观看| 国内精品福利| 欧美二区在线看| 国产成人精选| 欧美大奶子在线| 天天摸天天碰天天爽天天弄| 一本一道久久a久久精品综合蜜臀| 一道本在线观看| 老汉av免费一区二区三区| 正在播放久久| 国产精品自在| 国产精品麻豆va在线播放| 欧美激情二区| 亚洲国产天堂久久国产91| 黄色污污网站在线观看| 中文字幕日韩欧美一区二区三区| 久久久国产精品久久久| 国产欧美三级| 在线精品亚洲一区二区| 久久电影在线| 国产欧美久久一区二区| 免费看电影在线| 亚洲天堂av电影| 精品人妻少妇嫩草av无码专区| 精品久久久久久中文字幕| 国产精品成人无码免费| 豆国产96在线|亚洲| 无码人妻丰满熟妇区毛片| 一本一道久久综合狠狠老| 久久久久久久久久码影片| 欧美日韩卡一| 欧洲美女7788成人免费视频| 免费黄色网页在线观看| 亚洲精品不卡在线| 91好色先生tv| 岛国av在线不卡| 2018天天弄| 中文无字幕一区二区三区| 日日夜夜精品视频免费观看| 香蕉亚洲视频| 一本久道高清无码视频| 欧美wwwww| 欧美一区观看| 久久悠悠精品综合网| 成人欧美在线观看| 制服诱惑亚洲| 青青青国产精品一区二区| 91亚洲天堂| 中文字幕亚洲色图| 免费在线视频一级不卡| 欧美xfplay| 国产伦精品一区二区三区四区 | 亚洲一二三四久久| 欧美一区二区三区观看| 久久久综合网站| 中文字幕一区二区人妻电影丶| 狠狠色狠狠色合久久伊人| 任你操这里只有精品| 亚洲看片一区| 亚洲熟妇无码av在线播放| 99久久精品费精品国产风间由美| 麻豆成人在线播放| 欧美韩一区二区| 成人综合色站| 日本综合精品一区| 91免费版网站入口| 日韩三级成人| 国产日韩亚洲欧美| 免费一级欧美在线观看视频| 国产成人一区三区| 韩国成人漫画| 国产成人av在线播放| 欧美xxxxxx| 国产成人a亚洲精品| 欧美1级2级| 国产99视频精品免视看7| 性爽视频在线| 欧洲成人在线视频| 午夜激情成人网| 国产精品v日韩精品| 依依综合在线| 国产成一区二区| 成人久久网站| 91精品综合视频| 精品一区二区三区在线观看视频| 成人激情综合网| 伊人久久噜噜噜躁狠狠躁| 99免费在线观看视频| 一区二区三区免费在线看| 国产精品国产精品国产专区不卡| 国产福利一区二区精品秒拍| 国产亚洲自拍偷拍| 五月天亚洲一区| 日韩免费电影一区二区| 日韩成人激情| 亚洲色图都市激情| 亚洲伦理精品| 不卡av免费在线| 美女看a上一区| 亚洲激情在线看| 国产乱人伦偷精品视频不卡 | 91亚洲大成网污www| 国产传媒第一页| 欧美国产97人人爽人人喊| av资源在线免费观看| 一区二区三区四区高清精品免费观看 | 国产精品久久av| 成人午夜888| 国产欧美日韩在线播放| 一个色免费成人影院| 一区二区三区精品国产| 欧美不卡高清| 欧美性大战久久久久xxx| 人人超碰91尤物精品国产| 九色91porny| 91美女蜜桃在线| 黄色录像免费观看| 性做久久久久久久免费看| 91在线视频免费播放| 5566中文字幕一区二区电影| 男人天堂手机在线观看| 亚洲欧美日韩一区在线| 成人福利片网站| 日韩av不卡电影| 精品国产三区在线| 麻豆成人小视频| 51精产品一区一区三区| 日本少妇高潮喷水视频| 国内久久精品视频| 国产精品1000部啪视频| 亚洲男同性视频| 天天干,天天干| 精品久久久久久久久久久院品网| jizz在线观看视频| 97在线观看视频国产| 亚洲欧美专区| 欧美亚洲免费高清在线观看 | 中文字幕第80页| 成人免费高清视频在线观看| 黄色av免费播放| 黄色精品一区二区| 精品国自产拍在线观看| 亚洲视频电影图片偷拍一区| 黄色在线观看视频网站| 国产欧美亚洲视频| 色综合综合色| 婷婷五月综合缴情在线视频| 激情伊人五月天久久综合| 手机av免费看| 香蕉成人啪国产精品视频综合网| 亚洲一区二区激情| 亚洲欧美日韩高清| av美女在线观看| 97se亚洲综合| 99精品综合| 日韩爱爱小视频| 久久亚洲欧美国产精品乐播| 精品人妻在线播放| 欧美一区二区三区在线观看视频| av在线三区| 国产精品成人一区二区三区吃奶| 日韩深夜福利| 欧美国产亚洲一区| 成人av资源在线| 国产无码精品一区二区| 91精品国产综合久久精品app| 最新97超碰在线| 成人激情春色网| 亚洲91视频| 久久艹这里只有精品| 亚洲欧美激情视频在线观看一区二区三区| 天堂网一区二区| 亚洲一品av免费观看| 日本免费久久| 色之综合天天综合色天天棕色 | 午夜a成v人精品| 日韩在线视频观看免费| 午夜精品99久久免费| 国内毛片久久| av之家在线观看| 久久免费电影网| 亚洲成人av网址| 中文字幕亚洲国产| av在线精品| 日本a在线天堂| 国产凹凸在线观看一区二区| 久久这里只有精品免费| 精品剧情v国产在线观看在线| 黑人极品ⅴideos精品欧美棵| 国产传媒一区二区| 国产色综合网| 男人舔女人下部高潮全视频| 欧美视频一区二| av免费看在线| 国产高清一区二区三区| 国产精品亚洲欧美| 影音先锋制服丝袜| 欧美日韩免费观看一区三区| 黄色网址视频在线观看| 高清国产在线一区| 亚洲尤物精选| 欧美性猛交xxxx乱大交少妇| 91麻豆精品国产91久久久| 黑人极品ⅴideos精品欧美棵| 久久国产精品一区二区三区四区| 水野朝阳av一区二区三区| 国产小视频你懂的| 精品少妇一区二区三区视频免付费| jizz一区二区三区| 日本一区视频在线| 国产一区二区三区四区五区美女| 久久精品这里只有精品| 国产婷婷成人久久av免费高清| 成人不卡视频| 亚洲熟妇无码av在线播放| 国产午夜精品理论片a级大结局| 国产孕妇孕交大片孕| 欧美精品在线视频观看| 欧美亚洲色图校园春色| 在线观看岛国av| 天天av天天翘天天综合网色鬼国产| 成人av电影观看| 国产欧美日韩一区二区三区| 免费一级欧美片在线观看| 久久精品www| 在线观看国产欧美| 97青娱国产盛宴精品视频| 韩国日本美国免费毛片| 亚洲黄色av一区| 91视频在线观看| 久久视频在线观看中文字幕| 国内精品久久久久影院色| www欧美在线| 久久99热这里只有精品国产| 国产一区二区精品久| 黑人玩弄人妻一区二区三区|