C++11 std::function用法


轉自 http://www.hankcs.com/program/cpp/c11-std-function-usage.html

function可以將普通函數,lambda表達式和函數對象類統一起來。它們並不是相同的類型,然而通過function模板類,可以轉化為相同類型的對象(function對象),從而放入一個map里

 

在看Cocos2d-x的范例代碼時,隨處可見“很奇怪”的語法:

static std::function<Layer*()> createFunctions[] =
{
    CL(CameraTest1),
    //...
};

 

其中CL是一個宏,對應如下lambda表達式:

  1. #define CL(__className__) [](){ return __className__::create();}

還算好懂,感覺是個工廠模式,同時用宏模擬了接口。

但是這個std::function<Layer*()>卻讓我少見多怪了,翻開第五版《C++ Primer》,才知道原來是C++11的新特性——可調用對象模板類。一句話說明問題,std::function<Layer*()>代表一個可調用對象,接收0個參數,返回Layer*。

至於function的深入理解,還是用代碼說明吧。

#include <iostream>
#include <map>
#include <functional>
using namespace std;
 
// 普通函數
int add(int i, int j) { return i + j; }
// lambda表達式
auto mod = [](int i, int j){return i % j; };
// 函數對象類
struct divide
{
int operator() (int denominator, int divisor)
{
return denominator / divisor;
}
};
 
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
// 受限的map
map<char, int(*)(int, int)> binops_limit;
binops_limit.insert({ '+', add });
binops_limit.insert({ '%', mod });
// 錯誤 1 error C2664: “void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::insert(std::initializer_list<std::pair<const _Kty,_Ty>>)”: 無法將參數 1 從“initializer-list”轉換為“std::pair<const _Kty,_Ty> &&”
// binops_limit.insert({ '%', divide() });
 
// 更靈活的map
map<char, function<int(int, int)>> binops = 
{
{ '+', add },
{ '-', minus<int>() },
{ '*', [](int i, int j){return i - j; } },
{ '/', divide() },
{ '%', mod },
};
cout << binops['+'](10, 5) << endl;
cout << binops['-'](10, 5) << endl;
cout << binops['*'](10, 5) << endl;
cout << binops['/'](10, 5) << endl;
cout << binops['%'](10, 5) << endl;
system("pause");
return 0;
}
///////////////////////////End Sub//////////////////////////////////

 

如上所示,function可以將普通函數,lambda表達式和函數對象類統一起來。它們並不是相同的類型,然而通過function模板類,可以轉化為相同類型的對象(function對象),從而放入一個map里

另外我實際測試的結果來看,在VS2013編譯器下,上述代碼可以通過,而第五版《C++ Primer》第512頁第一行所言“錯誤:mod不是一個函數指針”並沒有發生錯誤,有可能是對C++11標准的不同實現吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM