template函数不是函数,std::endl而是template函数。
你不能传递一个template函数。但是,您可以传递一个表示重载集的函数对象。编写这样的函子非常容易:
struct endl_overloadset {
template<typename... Args>
auto operator()(Args&&...args)const
->decltype(std::endl( std::forward<Args>(args) ) )
{ return ( std::endl( std::forward<Args>(args) ) ) };
template<typename T,typename=typename std::enable_if<\
std::is_same< decltype(static_cast<T>( std::endl )), T >::value\
>::type>\
operator T() const { return std::endl; }
};
但我发现这有点像样板文件,所以写一些为你做这项工作的宏:
#define RETURNS(X) ->decltype(X) { return (X); } // C++11 lacks non-lambda return value deduction
#define OVERLOAD_SET(F) struct {\
template<typename... Args>\
auto operator()(Args&&...args)const\
RETURNS( F( std::forward<Args>(args)... ) )\
template<typename T,typename=typename std::enable_if<\
std::is_same< decltype(static_cast<T>( F )), T >::value\
>::type>\
operator T() const { return F; }\
}
static OVERLOAD_SET(std::endl) Endl;
然后传递Endl给您的f, 并调用Endl(Blah)最终执行std::endl(Blah). 类似地,分配Endl给变量或将其传递给方法与分配std::endl给变量或将其传递给方法(wrt重载决议)基本相同。
遗憾的是,OVERLOAD_SET不能在函数中使用,因为本地类型不能有template方法。如果它可以在函数中使用,那么:
f(1,2,3, OVERLOAD_SET(std::endl)() );
会做你想做的。但这将是您想要编程的语言,而不是您拥有的语言。(更好的是@Xeo 的提议,允许使用一些随机进一步滥用[]语法而不是依赖宏来自动生成重载集函子)。
现场示例,我将我的方法传递endl_functor给一个print方法,然后<<毫不费力地使用它。