天天看點

C++ lambda表達式使用lambda表達式進行函數式程式設計lambda表達式實作高階函數

C++ 11在語言中加入了lambda表達式,lambda表達式可以友善地構造匿名函數。當我們定義lambda表達式時,C++編譯器會建立一個匿名的與lambda表達式有關的類類型。

使用lambda表達式進行函數式程式設計

我們知道,在函數式程式設計語言中,比如

scheme

,函數作為一等公民,與普通的資料類型相同,可以作為函數的參數以及傳回值,可以很友善的實作高階函數等。 在C++中,我們可以借助于函數對象以及函數指針實作。 在C++ 11中,借助于lambda表達式,也可以實作高階函數。

将lambda表達式用作傳回值

定義在頭檔案中的std::function是多态的函數對象包裝,類似函數指針。它可以綁定至任何可以被調用的對象(仿函數、成員函數指針、函數指針和lambda表達式),隻要參數和傳回類型符合包裝的類型即可。傳回一個double、接受兩個整數參數的函數包裝定義如下:

function< double(int, int) > my_wrapper;
           

通過std::function,可以從函數中傳回lambda表達式,示例如下:

function<int(void)> multiplyBy2Lambda(int x)  
{  
    return [=]()->int{ return 2 * x; };  
}
           

這個函數的主體部分建立了一個lambda表達式,這個lambda表達式通過值捕捉所在作用域的變量,并傳回一個整數,這個傳回的整數是傳給multiplyBy2Lambda()的值的兩倍。這個multiplyBy2Lambda()函數的傳回值類型為 function

将lambda表達式用作參數

可以編寫lambda表達式作為參數的函數。例如,可通過這種方式實作回調函數。下面的代碼實作了一個testCallback()函數,這個函數接受一個整數vector和一個回調函數作為參數。這個實作疊代給定vector中的所有元素,并對每個元素調用回調函數,回調函數接受vector中每個元素作為int參數,并傳回一個布爾值。如果回調函數傳回false,那麼停止疊代。

//注意參數類型,第二個參數如果使用pass by reference,則必須加const修飾,否則編譯錯誤
//如果采用值傳遞,無影響
void testCallback(const vector<int>& vec, const function<bool(int)>& callback)  
{  
    for (auto i : vec)  
    {  
        if (!callback(i))  
            break;  
        cout << i << " ";  
    }  
    cout << endl;  
}  
           

測試:

auto callback = []( int i ) -> bool { return i < 6; };
vector<int> vec( 10 );
int index = 0;
generate( vec.begin(), vec.end(), [&index] {return ++index; } );

testCallback( vec, callback );
           

結果:

C++ lambda表達式使用lambda表達式進行函數式程式設計lambda表達式實作高階函數

lambda表達式實作高階函數

有關C++高階函數可以參看我的博文:C++高階函數

int sumInt( int a, int b ){
    int result { 0 };
    for ( int i = a; i <= b; ++i ) {
        result += i;
    }
    return result;
}

int sumCube( int a, int b ){
    int result { 0 };
    for ( int i = a; i <= b; ++i ) {
        result += i * i * i;
    }
    return result;
}

//advanced abstraction
template < class T >
T sumGeneric( T a, T b, const function< int( int ) >& func,  const function< void( int& ) >& next ){
    T result( 0 );
    for ( T i = a; i <= b; next( i ) ) {
        result += func( i );
    }
    return result;
}
           
上述示例中,前兩個求和函數有着相同的邏輯,可以進行抽象

sumGeneric

測試:

auto self = []( int i ) -> int { return i; };
auto inc = []( int& i ) -> void {  ++i; };
auto cube = []( int i ) -> int { return i * i * i; };

cout << "Normal Cal:" << endl;
cout << "sumInt( 1, 50 ):" << sumInt( 1, 50 ) << " sumCube( 1, 50 ):" << sumCube( 1, 50 );

cout << endl << "High Order Function:" << endl;
cout << "sumInt( 1, 50 ):" << sumGeneric( 1, 50, self, inc )
    << " sumCube( 1, 50 ):" << sumGeneric( 1, 50, cube, inc );
           

結果:

C++ lambda表達式使用lambda表達式進行函數式程式設計lambda表達式實作高階函數

代碼下載下傳位址:

https://github.com/bjut-hz/High-Order-Function