2016-12-31 83 views
1

標題可能有點混亂,所以我會更清楚地解釋它。如何使用不同參數的函數作爲函數參數

我有一個類,如:

class foo 
{ 
public: 

    foo(%Some function% *) { %Some function pointer% = %Some function%; } 

    %Some output% callFunction(%Some input%); 

private: 

    %Some function pointer% bar; 
} 

最好,我希望能夠給定函數存儲在%Some function pointer%整個班級使用,但是這是沒有必要的。

所以我的主要問題是: 我怎麼能創建一個真正的callFunction,可以採取在任何功能作爲輸入,與功能參數一起?

任何幫助表示讚賞!

+0

可能是這樣的:http://stackoverflow.com/questions/17805969/writing-universal-memoization-function-in-c11 –

+0

只是爲了澄清,你希望'foo :: callFunction'採取給定的參數它'%一些輸入%',你希望它調用'bar'傳遞這些參數並返回任何'bar'返回? IOW,有點像直通/代理功能? – greatwolf

+0

@greatwolf是的,這是我想要完成的,但我不確定如何去做。 – 0x22fe

回答

1

您將需要知道什麼地方會返回和參數類型。要麼固定在類中,要麼在模板參數中固定。

下面是固定在類的例子:

struct foo { 
    foo(std::function<int(std::string, double)> func) : bar{std::move(func)} {} 

    int callFunction(std::string s, double d) { 
     bar(std::move(s), d); 
    } 

private: 
    std::function<int(std::string, double)> bar; 
}; 

此方法不僅允許函數指針,但是任何功能狀物體太像的λ。

如果你不想被固定的類型,那麼你可以使用模板來指定函數對象的類型,你想換行:

template<typename F> 
struct foo { 
    foo(F func) : bar{std::move(func)} {} 

    template<typename... Args> 
    auto callFunction(Args&&... args) -> decltype(bar(std::declval<Args>()...)) { 
     return bar(std::forward<Args>(args)...); 
    } 

private: 
    F bar; 
}; 

template<typename F> 
auto make_foo(F f) { 
    return foo<F>{std::move(f)}; 
} 

此方法允許任何功能或功能類對象,並且也比其他解決方案更快,因爲它不會拖拽std::function開銷。這裏的缺點是你必須先使用make_foo之前的C++ 17。

然後,您可以使用上述解決方案是這樣的:

auto f1 = make_foo([](int i){ return i * 1.5; }); 
auto f2 = make_foo([]{}); 

double result = f1.callFunction(12); 
f2.callFunction(); 

如果您對C++ 17的開關翻轉,那麼你可以寫:

foo f1 = [](int i){ return i * 1.5; }; 
foo f2 = []{}; 

double result = f1.callFunction(12); 
f2.callFunction(); 

注意f1f2仍然是不同類型的實例。模板參數通過扣除隱藏。

+0

這是一個很好的答案!感謝您的幫助,以及C++ 17的提示。 – 0x22fe