提问人:spraff 提问时间:3/7/2019 更新时间:3/7/2019 访问量:147
为什么模板运算符<<不推断 std::endl?[复制]
Why doesn't template operator<< deduce std::endl? [duplicate]
问:
如果您取消注释第一个运算符定义,这将编译并运行:
#include <iostream>
struct logger
{
std::ostream &loggingStream;
logger(std::ostream &ls) : loggingStream(ls) {}
};
/*
logger &operator<<(logger &l, std::ostream & (*manip)(std::ostream &)) {
manip(l.loggingStream);
return l;
}
*/
template<typename T>
logger &operator<<(logger &l, const T &t) {
l.loggingStream << t;
return l;
}
int main() {
logger l(std::cout);
l << "Hello" << std::endl;
return 0;
}
有了评论:
error: no match for ‘operator<<’ (operand types are ‘logger’ and ‘<unresolved overloaded function type>’)
为什么我需要提供非模板重载来处理?endl
答:
1赞
YSC
3/7/2019
#1
因为,作为一个函数模板,std::endl
是关于模板参数推导的重载集;模板参数推导不能在重载集上起作用(当然,除非它只包含一个函数)。
为了说明这一点,请考虑:
template<class Function>
void functor(Function f)
{ f(0); }
void g(float) {}
void g(double) {}
functor(g);
没有理由偏袒一个版本而不是另一个版本,除非您明确专业化(很好),否则模板参数推导必须失败。g
functor
functor<void(float)>(f)
如果是模板,也是如此:http://coliru.stacked-crooked.com/a/8e27a45bbeedd979g
1赞
StoryTeller - Unslander Monica
3/7/2019
#2
std::endl
本身就是一个模板。当您遇到第一个重载时,可以通过与函数指针匹配来推导其参数。因为这是 TAD 发生的一个例子。
仅凭模板,有什么可以推断的?这两个模板都需要推导它们的参数。operator<<
评论