2014-10-10 53 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

也许制作第二个版本,它需要一个类的类型和一个签名,并为方法。 (我无法弄清楚如何使它对于方法透明地工作,而且我认为理论上它不能)。