日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 程序喵大人

你有沒有遇到過這種場景?

寫回調(diào)函數(shù)時,糾結(jié)到底該用“函數(shù)指針”還是“l(fā)ambda”?又或者,看到 C++ STL 里頻繁出現(xiàn)的“函數(shù)對象(仿函數(shù))”,忍不住一臉懵圈:這仨玩意兒,真的有那么多區(qū)別嗎?

今天,我們就來一口氣講清楚這三個在 C++ 中常見的“可調(diào)用對象”,不僅要分清它們的語法差異,更要搞懂 它們背后的性能差異實際應(yīng)用建議。

一、三個概念先講清

? 函數(shù)指針(Function Pointer)

最傳統(tǒng)的調(diào)用方式,C語言遺產(chǎn)。

void say_hello() {  std::cout << "Hello!\n"; }  void call(void (*func)()) {  func(); // 函數(shù)指針調(diào)用 } 

適合傳遞普通函數(shù),語法較繁瑣,對類型要求嚴格,不支持捕獲外部變量。

? 函數(shù)對象 / 仿函數(shù)(Function Object)

本質(zhì)是一個“重載了 operator() 的類”,可以像函數(shù)一樣使用對象。

struct Adder {  int operator()(int a, int b) const {  return a + b;  } }; 

優(yōu)點是可攜帶狀態(tài)、可內(nèi)聯(lián)優(yōu)化,STL 算法中大量使用,比如 std::sort 搭配比較器。

? Lambda 表達式

C++11 后的香餑餑,本質(zhì)是一個匿名的函數(shù)對象,寫法靈活、可捕獲變量。

auto adder = [](int a, int b) { return a + b; }; 

既能像函數(shù)指針那樣使用,又能像函數(shù)對象一樣攜帶狀態(tài),兼具兩者優(yōu)點。

二、核心問題:哪個性能更高?

結(jié)論先行:

函數(shù)對象 ≈ lambda > 函數(shù)指針 > std::function

是不是有點出乎意料?我們一個個講。

1. 函數(shù)對象 vs lambda:幾乎打平

因為 lambda 本質(zhì)就是編譯器幫你生成的匿名函數(shù)對象,它們都是 編譯期類型、可以被 內(nèi)聯(lián)優(yōu)化

舉個例子:

#include  #include   std::vector<int> vec = {3, 1, 4, 1, 5};  std::sort(vec.begin(), vec.end(), [](int a, int b) {  return a > b; }); 

這個 lambda 表達式,最終會被編譯器轉(zhuǎn)成類似如下結(jié)構(gòu):

struct Comp {  bool operator()(int a, int b) const { return a > b; } }; 

也就是說,從性能角度來看,lambda 和你手寫的函數(shù)對象效果是一樣的,區(qū)別只是有沒有名字而已。

優(yōu)勢:可內(nèi)聯(lián)優(yōu)化、零額外開銷劣勢:略顯抽象,捕獲變量時可能造成誤用(比如引用捕獲生命周期問題)

2. 函數(shù)指針:靈活但“冷門”

函數(shù)指針因為是 運行時確定的函數(shù)地址,所以不能內(nèi)聯(lián),性能略差。

void foo() { std::cout << "Hello\n"; } void run(void (*fp)()) { fp(); } 

相比函數(shù)對象或 lambda,它的開銷略高,主要體現(xiàn)在:

  • 無法內(nèi)聯(lián) → 函數(shù)調(diào)用成本更高
  • 不能攜帶狀態(tài) → 擴展性差
  • 類型不靈活 → 泛型編程不友好

但它依然有用武之地,比如你要調(diào)用某個庫函數(shù)的鉤子、處理 C 風(fēng)格 API(如 qsort)時,函數(shù)指針是必須的。

3. std::function:最靈活也最慢

std::function 是一個 類型擦除容器,可以包裝任意可調(diào)用對象(包括函數(shù)指針、lambda、仿函數(shù)等),代價是:

  • 要在堆上分配空間(如果可調(diào)用對象太大)
  • 無法內(nèi)聯(lián)
  • 性能開銷比前三者都大
std::function<void()> func = [] { std::cout << "Hello\n"; }; 

建議在 必須多態(tài)傳參統(tǒng)一接口 場景下使用,其他場景謹慎上。

三、實際開發(fā)怎么選?

場景 推薦使用 原因
STL 算法排序、查找等 lambda / 仿函數(shù) 編譯期優(yōu)化,零開銷
回調(diào)函數(shù) / 鉤子傳參 函數(shù)指針 簡潔直觀
狀態(tài)攜帶、靈活封裝 lambda / 仿函數(shù) 可維護性強
多態(tài)可調(diào)用對象封裝 std::function 提高通用性,犧牲性能

總結(jié):不要為了“酷”而用 lambda

雖然 lambda 是現(xiàn)代 C++ 的明星,但它并非萬能:

  • 如果你只需要傳個裸函數(shù)地址,用函數(shù)指針更輕量;
  • 如果你需要封裝復(fù)雜邏輯,lambda、仿函數(shù)才是首選;
  • 如果你想要靈活接口、動態(tài)傳參,那就老老實實用 std::function 吧。

?最重要的是:理解每種可調(diào)用對象的代價和場景,才是“高效”的真諦。


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉