精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

精品污污网站免费看| 久久一区欧美| 欧美精品一区二| 欧美丰满熟妇bbbbbb百度| 男女网站在线观看| 免费亚洲电影在线| 欧美另类69精品久久久久9999| 老司机午夜免费福利| 欧美性理论片在线观看片免费| 中文字幕在线一区免费| av色综合网| 久久人人爽人人爽人人片av免费| 亚洲午夜精品一区 二区 三区| 亚洲国产欧美久久| 国产成人美女视频| 亚洲精品日产| 一区二区三区成人在线视频| 欧美三级华人主播| 亚洲国产精品suv| 蜜臀91精品一区二区三区| 久久久久国产精品www| 老司机福利在线观看| 超碰地址久久| 欧美在线短视频| 亚洲熟妇av日韩熟妇在线 | 欧美xxxx老人做受| 免费看国产黄色片| 欲香欲色天天天综合和网| 亚洲人午夜精品天堂一二香蕉| 美女一区视频| 人妻va精品va欧美va| 精品在线一区二区| 日本最新高清不卡中文字幕| 福利一区二区三区四区| 亚洲五月综合| 久久久97精品| 成人午夜免费影院| 欧洲美女日日| 亚洲一区二区福利| 国产精品无码一区二区三区| 极品一区美女高清| 欧美大片顶级少妇| 女人扒开腿免费视频app| 精品无码三级在线观看视频 | 日本a在线免费观看| 日本电影全部在线观看网站视频 | 99成人在线观看| 欧美日韩伦理在线免费| 亚洲欧美国产精品专区久久| 一级特级黄色片| 久久悠悠精品综合网| 精品国产乱码久久久久久浪潮| 国产 日韩 亚洲 欧美| 免费视频网站www| 日韩欧美视频| 在线亚洲欧美视频| 2019男人天堂| 四虎成人精品永久免费av九九| 亚洲视频在线看| 日本性高潮视频| 国产精品免费大片| 国产午夜一区二区| 人妻熟人中文字幕一区二区| 精品日韩欧美一区| 色视频www在线播放国产成人| 中文字幕一区二区三区人妻| 一本色道久久综合狠狠躁的番外| 亚洲男人天堂视频| 中字幕一区二区三区乱码| 青草国产精品| 久久成人18免费网站| 九九九免费视频| 1000部精品久久久久久久久| 69av成年福利视频| 男人天堂视频在线| 精品亚洲成a人| 99久久99久久| 天堂√在线中文官网在线| 久久综合色播五月| 亚洲国产精品123| 91高清在线| 一区二区高清在线| 六月激情综合网| 国产一区高清| 精品国产亚洲一区二区三区在线观看| 久久精品老司机| 99国产精品一区二区| 欧美激情一二区| 在线观看亚洲黄色| 国产高清在线精品| 欧美黄色直播| 污污网站在线看| 一本一本大道香蕉久在线精品 | 久草在线新免费首页资源站| 日韩欧美国产成人| 亚洲第一色av| 天堂99x99es久久精品免费| 中文字幕国产精品| 精品一级少妇久久久久久久| 日韩高清中文字幕一区| 99在线观看视频| 福利成人在线观看| 亚洲自拍偷拍九九九| 男人插女人下面免费视频| 日韩欧美中文在线观看| 亚洲美女自拍视频| 欧美丰满艳妇bbwbbw| 日韩精品一二三四| 成人一区二区在线| 在线免费看黄网站| 激情久久av一区av二区av三区| 日韩一级免费片| 欧美美女在线直播| 久久夜色精品国产欧美乱| 久久久黄色大片| 国产精品影视天天线| 三区精品视频观看| 两个人看的在线视频www| 欧美一区日本一区韩国一区| av中文字幕免费观看| 国一区二区在线观看| 国产主播欧美精品| 国产精品一区二区婷婷| 黄色成人av网| 国内自拍偷拍视频| 国产精品久久观看| 国产精品久久久久9999| 深夜影院在线观看| 亚洲成人福利片| 永久看看免费大片| 91偷拍一区二区三区精品| 激情欧美日韩一区| 亚洲精品女av网站| 日本亚洲精品| 欧美在线制服丝袜| 成人网站免费观看| 亚洲久久在线| 国产成人精品一区二区三区福利| 久热国产在线| 欧美卡1卡2卡| 亚洲女同二女同志奶水| 蜜臂av日日欢夜夜爽一区| 日本一区二区不卡高清更新| 亚洲一级少妇| 亚洲伦理中文字幕| 人妻 日韩精品 中文字幕| 91在线视频观看| 日日摸日日碰夜夜爽无码| 综合激情五月婷婷| 欧美激情日韩图片| 男人天堂av网| 亚洲成a人片在线不卡一二三区| 日本精品一二三区| 亚洲精品专区| 蜜桃麻豆91| jizzjizz少妇亚洲水多| 中文字幕av一区中文字幕天堂| 少妇又紧又色又爽又刺激视频| 国产亚洲自拍一区| www.亚洲高清| 在线精品国产| 国产乱人伦精品一区二区| 美女扒开腿让男人桶爽久久软| 日韩精品在线观看一区二区| 日韩精品一区二区亚洲av观看| 中文字幕巨乱亚洲| www.亚洲自拍| 在线欧美三区| 日产中文字幕在线精品一区| 欧美美女被草| 欧美激情精品久久久久久大尺度| 天堂av在线免费| 在线亚洲高清视频| 任我爽在线视频| 大胆亚洲人体视频| 久久久久久久久久久久久国产精品| 国产欧美日韩精品一区二区免费| 国产免费久久av| 亚洲小说区图片区都市| 亚洲国产一区二区三区在线观看| 欧美一区二区三区网站| 国产精品看片你懂得| 人妻精品久久久久中文字幕69| 中文亚洲免费| 伊人久久婷婷色综合98网| 99热这里只有精品首页| 欧美中文字幕在线播放| 老司机免费在线视频| 亚洲成人黄色在线观看| 性高潮视频在线观看| 一区二区三区波多野结衣在线观看| www.超碰97| 国产一区二区三区在线看麻豆| 国产美女网站在线观看| 99久久综合狠狠综合久久aⅴ| 国产九色91| 日韩欧美专区| 欧美壮男野外gaytube| 八戒八戒神马在线电影| 亚洲精品在线91| 精品国产一级片| 欧美性受xxxx黑人xyx| 国产一级aa大片毛片| 国产精品天天摸av网| 久久久老熟女一区二区三区91| 日韩电影在线观看网站| 日韩国产一级片| 午夜精品毛片| 日韩精品欧美专区| 国产精品午夜av| 91久久国产婷婷一区二区| 悠悠资源网亚洲青| 久久久久成人网| 好了av在线| 在线观看久久久久久| 香蕉久久一区二区三区| 日韩欧美一级二级三级| 做爰视频毛片视频| 懂色av中文一区二区三区天美| 亚洲国产成人精品综合99| 中文字幕精品一区二区精品绿巨人| 亚洲久久久久久| 国产·精品毛片| 久久6免费视频| 蜜桃av噜噜一区| 99热这里只有精品在线播放| 亚洲欧美春色| 97干在线视频| 国产精品v欧美精品v日本精品动漫| 亚洲欧美日韩国产成人综合一二三区| 亚洲v天堂v手机在线| 精品高清视频| 韩国精品福利一区二区三区| 91久久国产自产拍夜夜嗨| 在线免费观看亚洲| 国产美女精品免费电影| 久久久加勒比| 国产精品青草久久久久福利99| 欧美香蕉视频| 日韩美女av在线免费观看| 中文在线最新版地址| 欧美在线一级va免费观看| 亚洲淫成人影院| 国产成人jvid在线播放| 国产超碰精品| 国产精品美女无圣光视频| 日韩精品影片| 国产精品视频男人的天堂| 日韩精品麻豆| 国产日韩欧美一二三区| 日韩色性视频| 成人在线视频网址| silk一区二区三区精品视频| 国产精品一码二码三码在线| 久久夜色电影| 日本一区二区在线视频观看| 日本午夜一区| 五月天在线免费视频| 欧美一区二区| 成人在线观看你懂的| 性久久久久久| 亚洲欧洲日本精品| 国内精品久久久久影院薰衣草 | 亚洲网一区二区三区| 国产成人看片| 免费精品国产| 一区二区三区四区国产| 雨宫琴音一区二区三区| 岛国大片在线播放| 久久久亚洲人| 亚洲精品国产一区二区三区| 日本一区视频在线播放| 色香蕉在线视频| 亚洲精品成人av| 韩国三级在线观看久| 日韩一区二区三区在线播放| 性欧美1819sex性高清大胸| 国内精品久久久久久| 成人性生交大片免费观看网站| 国产精品久久久久久久久久免费 | 国产一区二区三区黄| 色综合综合网| www.黄色网址.com| 国产欧美日韩综合一区在线播放| 黄色片视频在线播放| 激情综合五月婷婷| 日本一区二区在线免费观看| 欧美国产日韩在线观看| 欧美人妻精品一区二区免费看| 欧美日韩人人澡狠狠躁视频| 夜夜骚av一区二区三区| 精品久久99ma| 一区二区三区视频网站| 久久久视频在线| 97精品国产综合久久久动漫日韩| 99久久国产免费免费| 精品免费在线| 精品久久久久久久久久中文字幕| 精品中文字幕一区二区小辣椒| www.超碰97| 亚洲最新在线观看| 中文字幕av影视| 日韩精品极品视频| 超碰在线观看免费| 国产精欧美一区二区三区| 亚洲一区电影| 一本一生久久a久久精品综合蜜| 国产精品亚洲产品| 国产xxxxhd| 欧美国产精品专区| 国产成人亚洲精品自产在线| 欧美一区二区在线看| 国产理论电影在线观看| 欧美亚洲激情在线| 国产精品白丝久久av网站| 日韩精品久久久免费观看| 亚洲激情专区| 午夜精品久久久久久久99热影院| 久久综合久久久久88| 国产亚洲成人精品| 制服丝袜日韩国产| av资源在线观看免费高清| 欧美亚洲视频在线看网址| 一级毛片精品毛片| 裸体大乳女做爰69| 久久99国产精品麻豆| 国产又粗又硬视频| 日本韩国一区二区| 亚洲av毛片成人精品| 韩国欧美亚洲国产| 国产厕拍一区| 午夜国产在线观看| 日韩精品在线第一页| 污视频网站在线免费| 成人精品网站在线观看| 欧美另类69xxxxx| 国内外成人激情视频| 成人午夜免费视频| 国产大学生自拍| 欧美日韩国产美| www 日韩| 国产精品久久一区主播| 国内精品久久久久久久影视简单| 国产91在线免费| 99国产一区二区三精品乱码| 国产一级aa大片毛片| 精品精品国产高清a毛片牛牛| 一色桃子av在线| 亚洲淫片在线视频| 欧美永久精品| 久久久久久久穴| 一区二区三区国产豹纹内裤在线| 性欧美videos另类hd| 久久久久久久久国产| 精品国内亚洲2022精品成人| 丁香花在线影院观看在线播放| 波多野结衣中文字幕一区 | 狠狠久久婷婷| 97精品人人妻人人| 欧美日韩国产一区中文午夜| 奇米影视888狠狠狠777不卡| 国产成人精品优优av| 三级电影一区| 人妻换人妻仑乱| 图片区小说区区亚洲影院| 涩涩视频在线观看免费| 国产精品国产三级国产专播精品人| 区一区二视频| 欧美熟妇另类久久久久久多毛| 午夜在线成人av| 九色在线播放| 成人午夜在线视频一区| 亚洲视频高清| 波多野结衣av在线观看| 欧美精品一二三| wwwww亚洲| 日韩视频在线观看国产| 国产精品一区专区| www.国产一区二区| 久久天天躁狠狠躁夜夜av| 超碰97久久国产精品牛牛| 中文字幕无码不卡免费视频| 中文字幕亚洲在| 色窝窝无码一区二区三区| 国产精品久久综合av爱欲tv| 欧美88av| 熟女少妇内射日韩亚洲| 欧美一区国产二区| 黑人巨大精品欧美一区二区桃花岛| 在线视频不卡国产| 99久久综合国产精品| 在线免费观看高清视频| 97精品视频在线播放| 日韩欧美1区| 大尺度做爰床戏呻吟舒畅| 欧美视频中文一区二区三区在线观看| 日本动漫理论片在线观看网站| 欧美日韩国产综合视频在线| 激情图片小说一区| 欧美精品韩国精品|