2014-10-10 52 views
2

這是一個後續問題How template function chooses parameter?演員的std :: ENDL一個函數指針

@Kerrek SB提出了以下解決方案:

Func(static_cast<std::ostream&(&)(std::ostream&)>(std::endl)); 

我還發現,下面的代碼工作對我來說:

Func(static_cast<std::ostream&(*)(std::ostream&)>(std::endl)); 

問題>哪一個是優選的方法?

+2

與數組類似,函數和函數引用將*隱式*衰減爲指向函數的指針。函數調用操作符'()'與兩者兼容。我傾向於明確創建和使用函數指針(所以第二個會說'&std :: endl'),但它確實是一個風格問題。 – 2014-10-10 15:41:11

+0

或更簡單的'Func (std :: endl)'。 – Jamboree 2014-10-10 16:13:53

+0

@BenVoigt:嚴格來說,函數調用操作符'()'只能用函數指針作爲前綴。如果給它一個函數類型或引用函數類型的表達式,該表達式將在'()'操作符看到它之前隱式衰減到一個指針。使用函數類型的表達式作爲'()'的前綴不僅是非法的;不可能。 (除非我錯過了一些時髦的C++ 42標準特性,這使得它在一些奇怪的角落情況下成爲可能。) – 2014-10-10 21:43:47

回答

0

我這樣做:

template<class Sig> 
struct reference_to_function {}; 
template<class R, class... Args> 
struct reference_to_function<R(Args...)> { 
    using type = R(&)(Args...); 
}; 
template<class Sig> 
using sig_t = typename reference_to_function<Sig>::type; 

template<class Sig> 
sig_t<Sig> pick_signature(sig_t<Sig> f) { return f; } 

則:

Func(pick_signature<std::ostream&(std::ostream&)>(std::endl)); 

這使得它明確了我想做的事,而不是static_cast

也許製作第二個版本,它需要一個類的類型和一個簽名,併爲方法。 (我無法弄清楚如何使它對於方法透明地工作,而且我認爲理論上它不能)。