2015-05-29 66 views
1

我想使用函數指針和lambdas一起使用一個接口。我決定使用std::function,但我很快發現它不能自己處理重載函數。如何使用一個接口傳遞函數指針和lambda's

實施例:

void foobar(double i_double){std::cout << "double argument" << i_double << std::endl;} 
void foobar(){std::cout << "no argument" << std::endl;} 
void foobar(int){std::cout << "int argument" << std::endl;} 

std::function<void(double)> func = static_cast<void(*)(double)>(&foobar); 

此代碼僅通過使用static_cast編譯。由於在我們公司我們有相當多的超載功能,這太麻煩了。現在我決定實現兩個接口:一個用於std::function對象,另一個用於函數指針,儘管我真的很想將函數指針也包裝在std::function對象中(在調用端沒有附加代碼)。

這個問題的任何「很好」的解決方案?

編輯: 我將使用它的方式是一個大框架的一部分,但歸結爲下面的代碼。我希望下面的代碼清楚地說明用例。

namespace 
{ 
    bool IsAllowed(string) {...} 
    bool IsAllowed(int) {...} 
} 

CIteratorFilter<String>(listofstrings, IsAllowed); 

CSomeObject object; 
CIteratorFilter<String>(listofstrings, 
    [&object](String i_string) { return object.IsAllowed(i_string); } 
); 

目前這個CIteratorFilter需要實現兩個函數指針和std::function接口,這是不是在我看來很不錯。

+0

告訴我們你打算如何使用這個。它看起來像一個XY問題 – bolov

回答

1

請參閱... XY問題。

這或任何類似不需要:

std::function<void(double)> func = static_cast<void(*)(double)>(&foobar); 

您需要使用模板:

template <class Func> 
CIteratorFilter<String>(listofstrings, Func func) { 
    // call func whatever it may be function pointer, lambda, callable object: 
    func(..whatever params...); 
} 

可以用完美fowarding爲func如果你想

+0

CIteratorFilter本身就是模板,我可以使模板構造函數成爲可能並將參數轉發給基類構造函數嗎? – cageman

+0

你的語法實際上並不是有效的C++,所以我盡我所能猜測你的代碼實際上是怎麼看的。有可能的。發佈實際的代碼(非常小,但可編譯) – bolov

+0

嗯,我試圖做到這一點,但CIteratorFilter上的模板構造函數不能用於重載方法的函數指針..與以前相同的問題:( – cageman

0

爲什麼不使用非捕獲lambda與正確的參數,並調用foobar函數?

std::function<void(double)> func = [](double d){ foobar(d); }; 

這是我能想到的最好的。

+0

甚至更​​好:'auto func =' – bolov

+0

我想我應該提到,目前已經存在一個大框架..這意味着我需要重寫所有代碼使用lamba的到處,這是醜陋的我認爲不需要。 – cageman

0

按C具有宏魔法的++ 11功能。

#define FUNCTION(RETURN, NAME, ...) \ 
    std::function<RETURN (__VA_ARGS__)>(static_cast<RETURN(*)(__VA_ARGS__)>(&NAME)) 

用法:

auto func1 = FUNCTION(void, foobar, double); 
auto func2 = FUNCTION(void, foobar); 
auto func3 = FUNCTION(void, foobar, int); 

如果你不想使用可變參數,然後下面是這樣做的另一種方法:

#define FUNCTION(RETURN, NAME, PARAMETERS) \ 
    std::function<RETURN PARAMETERS>(static_cast<RETURN(*)PARAMETERS>(&NAME)) 

用法:

auto func1 = FUNCTION(void, foobar, (double)); 
auto func2 = FUNCTION(void, foobar,()); 
auto func3 = FUNCTION(void, foobar, (int)); 
相關問題