2017-07-06 77 views
15

我有一個模板功能,我們稱之爲「客戶」:如何使用不同數量的默認參數來包裝函數以使其只有一個參數?

template<typename T> 
void client(T (*func)(const std::string&), const std::string& s) {} 

再就是,但一些「適配者」的功能,所有具有相同類型的第一個,非默認的論點,以下參數在數量上有所不同,並且具有默認值:

void adaptee_one(const std::string&, int i = 1, char* c = nullptr) {} 
void adaptee_two(const std::string&, float* f = nullptr) {} 

上述功能是給定的。現在我想要做的是將它們作爲第一個參數傳遞給上面的client<>()函數,我只關心傳遞第一個參數const std::string&。所以,我做到以下幾點:

void bindAdapteeOne(const std::string& s) { 
    return adaptee_one(s); 
} 

void bindAdapteeTwo(const std::string& s) { 
    return adaptee_two(s); 
} 

再經過bindAdapteeX()client<>()

我想要做的是自動包裝或有一個(模板)包裝,而不是每個適配器。我覺得這可能是variadics的情況,但幾乎沒有關於如何正確應用它們的想法。

C++ 11很好,如果絕對必要的話,C++ 14是很好的。

+0

是否允許使用lambda? – AndyG

+0

@AndyG它位於任何類之外的命名空間中,所以我認爲是的,只要有一個理智的地方來保存它們。 – iksemyonov

+1

@rici因爲[不起作用](https://wandbox.org/permlink/WYzQfhLbPA7KXIEy)。 – Barry

回答

12

C++ 11很好,如果絕對必要的話,C++ 14是很好的。

C++ 11解決方案在這裏。

我想要做的是自動包裝或有一個(模板)包裝,而不是每個適配器一個。

我不會這麼做。你可以簡單地使用非捕獲lambda表達式,讓他們衰減到函數指針:

client (+[](const std::string& s) { return adaptee_one(s); }, "foo"); 

我不認爲他們包裹在模板的東西或任何會給你一個解決方案,更可讀或易於使用。


作爲一個最小的,工作示例:

#include<string> 

template<typename T> 
void client(T (*func)(const std::string&), const std::string& s) {} 

void adaptee_one(const std::string&, int i = 1, char* c = nullptr) {} 
void adaptee_two(const std::string&, float* f = nullptr) {} 

int main() { 
    client (+[](const std::string& s) { return adaptee_one(s); }, "foo"); 
} 
+2

「加號」不是拼寫錯誤嗎?我以前從來沒有見過。 – iksemyonov

+6

@iksemyonov這是一個[正面lambda](https://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this):)只是開玩笑,它是用來將lambda轉換成函數指針藉助於其轉換運算符(請參閱鏈接問題)。 – Rakete1111

+0

謝謝!天啊。很高興我發佈了這個問題 - 將永遠不會知道。 – iksemyonov

7

這是那個時代,其中一個宏可以幫助之一:

#define WRAP_FN(f) +[](std::string const& s) -> decltype(auto) { return f(s); } 

雖然你可以只寫一個內嵌的身體,而不是。


沒有什麼可以做的了。問題是,默認的參數是不是在函數的簽名可見的,所以一旦你進入了類型系統,有沒有辦法來區分:

void works(std::string const&, int=0); 
void fails(std::string const&, int ); 

那些兩者都是void(*)(std::string const&, int)。所以你不能有一個函數模板或類模板包裝 - 你需要用一個lambda(或者一個包裝lambda的宏)來內聯。

+0

'decltype(auto)'不能作爲返回類型嗎? –

+0

謝謝!模板解決方案包含一些我必須查找的內容,但不管它看起來相當可怕。沒有辦法或需要在這裏使用可變參數來解釋參數的不同數量? – iksemyonov

+0

@iksemyonov你說你只想傳遞'std :: string',你需要什麼「不同數量的參數」? –

0

我在想我會創建一個包裝你的參數並讓客戶端接受該類的實例的類。這樣,您只有一個參數,其中包含您希望的許多參數。

該參數包裝也將提供默認值,並允許您在派生類中爲特定目的對它們進行優化。

與lambda表達式相比,這可能會更自我記錄一些。

誰知道,當它從一個文件讀取和寫入參數的時候,那麼包裝類就是完成這個任務的理想場所。

相關問題