為什麼傳遞函數指針而不是函數本身?

比如指定unique刪除器的時候,還有不允許函數的數組,是因為函數不是對象嗎?

補充,指的是類型比如map&,不過懂了,當時大腦不太清醒。。。囧。。。


函數本身是什麼意思。。。囧。。。你要把那一坨二進位複製來複制去。。?


我想你的函數本身指的是函數閉包吧,然而在Cpp中不存在函數閉包的概念。Lua中的函數是閉包,可以參考對比。


std::function符合你的想法


最好是了解一下圖靈機和馮諾依曼架構的概念,對這個問題的理解就會清楚很多。

https://zh.wikipedia.org/wiki/%E5%86%AF%C2%B7%E8%AF%BA%E4%BC%8A%E6%9B%BC%E7%BB%93%E6%9E%84

簡單地來說,在計算機中,數據和指令是分離的,以完全不同的方式存儲。儘管今天的編程語言或多或少地加入了函數式編程的特性,但是計算機的底層架構依然是純粹的過程式編程,數據和指令分離。那麼,出於C++的天性,當它在語言層面支持一些函數式的寫法的時候,就要你理解它是如何將數據與指令結合的一些抽象結構拆分成單一的數據和單一的指令。

數組和對象都只能存儲數據,不能存儲指令,而函數內部是指令。函數指針是數據,所以C++先在指令區創建一個函數,然後在數據區創建一個指向它的指針。lambda表達式也會創建一個匿名類,用來存儲它捕獲的閉包中的數據。


C++ 是編譯語言,源代碼本身不能執行,源代碼到機器碼需要編譯,編譯得到的可執行文件並不包括編譯器。二進位代碼只能通過編譯過程得到,運行時產生不了,也修改不了。這說明,如果要需要傳遞函數代碼,只可能傳遞編譯後的函數,即可執行的二進位代碼,而且還不能改變。

一個不能改變的可執行函數代碼能用來幹什麼?它只能被執行。由於函數可能調用外部的函數或者庫,這段可執行代碼拿出了這個程序也就用不了了,所以這段代碼只能在本機本程序中執行,用網路傳走或者額外保存起來也沒什麼價值。這說明,對於一個可能需要傳遞的函數,你能關心的也只是它能不能執行,別的都沒用。

現在問題來了,傳遞一個小小的指針能執行,傳遞一段長長的代碼也能用來執行。為什麼要舍小取大呢?

話說回來,說 C++ 不能傳遞函數,這也不完全對。C++ 參數可以傳遞 Functor 對象,可以傳遞 lambda 表達式對象,這些都是程序運行時可以有狀態信息,可以在運行時生成和改變的類似函數的對象——其實是重載了 operator() 的對象。所以在有需要的時候,就會傳遞這種對象本身了。


C++/C家族 都不支持函數變數,只有函數常量(不知這個詞是否準確,是我自創的,匆噴)函數指針

C++是使用對象的方法,將函數指針封裝起來了,將函數轉換成對象,然後編寫一大堆的演算法支持函數對象。通過抽象,讓函數看起來像變數一樣。


因為函數有一份就夠了,不需要重複的兩份浪費內存,一份函數可以被並發的執行


推薦閱讀:

TAG:C編程語言 | C | 指針 |