2014-02-14 285 views
1

我已閱讀關於lambdas,函數指針,匿名函數以及其他相關內容的文章/文章,但沒有看到(我認爲)我期待的是什麼將匿名函數作爲參數傳遞給另一個函數(C++)

這似乎是完成這應該是非常簡單的,但說我有一個函數包含的東西,我總是想要做的時候調用,但每次我打電話時,我希望它運行我描述的功能(只需要使用一次)在參數(這個匿名函數是唯一的參數)。

假設這個函數接受我的匿名函數作爲它的參數在main.cpp中,所以它從main調用是否有可能以一種簡單的方式實現它?

基本上我試圖找出在C++的語法從這個打算:

// Some function with partially duplicated code 
void OriginalA() 
{ 
    DoThingsA(); 

    // unique code 

    DoThingsB(); 
} 

// Another function with partially duplicated code 
void OriginalB() 
{ 
    DoThingsA(); 

    // unique code 

    DoThingsB(); 
} 

要這樣:

// Encapsulate shared functionality 
// <param name="action">User defined action</param> 
void UniqueWrapper(Action action) 
{ 
    DoThingsA(); 

    action(); 

    DoThingsB(); 
} 

// New implmentation of A 
void NewA() 
{ 
    UniqueWrapper(() => 
    { 
     // unique code 
    }); 
} 

// New implementation of B 
void NewB() 
{ 
    UniqueWrapper(() => 
    { 
     // unique code 
    }); 
} 

,我發現因爲這裏爲#1:http://www.wildbunny.co.uk/blog/2012/11/01/10-steps-to-becoming-a-better-programmer/

但是像這樣的設置,字面上你需要做的所有事情都是:

theFunctionName(() => { /*unique things to do*/ }); 

如果^^是合法的調用語法,那麼我只是不確定參數在函數名的定義中是如何看起來的,顯然它不是(Action action),就像上面的例子。

template<typename Function> 
void UniqueWrapper(Function action) { 
    DoThingsA(); 
    action(); // call the passed in function 
    DoThingsB(); 
}; 

這樣稱呼它:

回答

1

有多種方法可以做到這一點,但不是所有將在所有平臺上工作(例如,因爲他們會要求C++ 11個功能(lambda表達式)。

更經典的做法是這樣的(沒有一個匿名函數):

#include <iostream> 

typedef void(*Action)(); 

void UniqueWrapper(Action action) { 
    std::cout << "Generic Code 1" << std::endl; 
    action(); 
    std::cout << "Generic Code 2" << std::endl; 
} 

void CustomAction(void) { 
    std::cout << "Custom Code" << std::endl; 
} 

int main(int argc, char **argv) { 
    UniqueWrapper(&CustomAction); 
    return 0; 
} 

當然,你可以使用一些宏觀有心計,使這個更「動態」

一旦你接受了C++ 11的代碼,以及(這是需要有lambda表達式。如解釋),你可以做這樣的事情:

#include <iostream> 

typedef void(*Action)(); 

void UniqueWrapper(Action action) { 
    std::cout << "Generic Code 1" << std::endl; 
    action(); 
    std::cout << "Generic Code 2" << std::endl; 
} 

int main(int argc, char **argv) { 
    UniqueWrapper([](){ 
      std::cout << "Custom Code" << std::endl; 
     }); 
    return 0; 
} 

當然,還有更多空間的變化,例如,你可以使用std::function,而不是一個函數指針。

+0

這隻適用於你在lambda中沒有捕獲任何東西。只要你這樣做,它會以微妙的方式破碎。 IMO在C++中接受可調參數的最好方法是模板(它適用於沒有開銷的所有內容)。 'std :: function'總是會引入開銷,函數指針可以防止內聯,並且不適用於函子。如果無論出於何種原因都不能使用模板,這些實際上只是後備。 – pmr

3

與更換Action參數

void NewA() { 
    UniqueWrapper([]() {}); 
    //   ^^^^^^^ 
    //  C++11 lambda syntax 
} 

而是一個lambda你也可以使用函數指針,(使用std::mem_fn)成員函數,或仿函數。每種可調用對象都可以工作。

相關問題