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 的提议,允许使用[] 语法的一些随机进一步滥用来自动生成重载集函子,而不是依赖于宏)。
Live example,我将我的endl_functor 传递给print 方法,然后毫不费力地在其上使用<<。