2014-10-01 75 views
6
#include <iostream> 
#include <ostream> 

template<typename T> 
void Func(const T& val) 
{ 
    std::cout << "const T& val\n"; 
} 

void Func(const char* p) 
{ 
    std::cout << "const char * p\n"; 
} 

void Func(std::ostream & (*manip)(std::ostream &)) 
{ 
    std::cout << "ostream\n"; 
} 

int main() 
{ 
    Func(std::endl); 
    Func("aaa"); 
} 

观察:模板函数如何选择参数?

1>没有void Func(std::ostream & (*manip)(std::ostream &)),行Func(endl);会导致编译器错误。我认为这个问题是由于模板函数void Fun(const T& val)只能使用T类型的函数指针。

2>不void Func(const char* p),线Func("aaa");运行正常。我假设原因是类型T可以是const char*

问题>这些是正确的参数?

谢谢

+3

是第一功能真的叫乐趣,而不是Func键,或者是一个错字? – happydave 2014-10-01 13:53:57

+0

@happydave,我修改了代码和问题。 – q0987 2014-10-01 13:55:07

+0

在没有const char *重载的第二种情况下,T被推断为char [4]。 – 2014-10-01 14:02:59

回答

8

std::endl本身就是一个函数模板,所以你不能有Func模板实参推演,除非你确实指定了功能。下面应该工作:

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

另一种方法(感谢@ 0x499602D2)是指定模板参数:

Func(std::endl<char, std::char_traits<char>>); 
+0

为什么演员的语法不是以下内容? 'Func键(的static_cast <性病:: ostream的&(*)(标准:: ostream的&)>(标准:: ENDL));' – q0987 2014-10-01 14:06:15

+0

否,Kerrek明确地说,'的std :: endl'是_not_这一点。你真的准备好了吗?例如,参见[this](http://en.cppreference.com/w/cpp/io/manip/endl)。 – Useless 2014-10-01 14:11:17

+0

@无用,我删除了我的评论。 THX – q0987 2014-10-01 14:13:24