当重载operator <<时,std :: endl是未知类型

当重载operator <<时,std :: endl是未知类型

我重载了运算符<<

template <Typename T>UIStream& operator<<(const T);UIStream my_stream;my_stream << 10 << " heads";

工作但是:

my_stream << endl;

给出编译错误:

错误C2678:二进制'<<':找不到哪个运算符带有'UIStream'类型的左操作数(或者没有可接受的转换)

my_stream << endl工作的工作是什么?


qq_笑_17
浏览 931回答 3
3回答

汪汪一只猫

std::endl是一个函数,std::cout通过实现operator<<获取具有相同签名的函数指针来利用它std::endl。在那里,它调用函数,并转发返回值。这是一个代码示例:#include&nbsp;<iostream>struct&nbsp;MyStream{ &nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;<typename&nbsp;T> &nbsp;&nbsp;&nbsp;&nbsp;MyStream&&nbsp;operator<<(const&nbsp;T&&nbsp;x) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;*this; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;function&nbsp;that&nbsp;takes&nbsp;a&nbsp;custom&nbsp;stream,&nbsp;and&nbsp;returns&nbsp;it &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;MyStream&&nbsp;(*MyStreamManipulator)(MyStream&); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;take&nbsp;in&nbsp;a&nbsp;function&nbsp;with&nbsp;the&nbsp;custom&nbsp;signature &nbsp;&nbsp;&nbsp;&nbsp;MyStream&&nbsp;operator<<(MyStreamManipulator&nbsp;manip) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;call&nbsp;the&nbsp;function,&nbsp;and&nbsp;return&nbsp;it's&nbsp;value &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;manip(*this); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;define&nbsp;the&nbsp;custom&nbsp;endl&nbsp;for&nbsp;this&nbsp;stream. &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;note&nbsp;how&nbsp;it&nbsp;matches&nbsp;the&nbsp;`MyStreamManipulator` &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;function&nbsp;signature &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;MyStream&&nbsp;endl(MyStream&&nbsp;stream) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;print&nbsp;a&nbsp;new&nbsp;line &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;do&nbsp;other&nbsp;stuff&nbsp;with&nbsp;the&nbsp;stream &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;std::cout,&nbsp;for&nbsp;example,&nbsp;will&nbsp;flush&nbsp;the&nbsp;stream &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream&nbsp;<<&nbsp;"Called&nbsp;MyStream::endl!"&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;stream; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;this&nbsp;is&nbsp;the&nbsp;type&nbsp;of&nbsp;std::cout &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;std::basic_ostream<char,&nbsp;std::char_traits<char>&nbsp;>&nbsp;CoutType; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;this&nbsp;is&nbsp;the&nbsp;function&nbsp;signature&nbsp;of&nbsp;std::endl &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;CoutType&&nbsp;(*StandardEndLine)(CoutType&); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;define&nbsp;an&nbsp;operator<<&nbsp;to&nbsp;take&nbsp;in&nbsp;std::endl &nbsp;&nbsp;&nbsp;&nbsp;MyStream&&nbsp;operator<<(StandardEndLine&nbsp;manip) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;call&nbsp;the&nbsp;function,&nbsp;but&nbsp;we&nbsp;cannot&nbsp;return&nbsp;it's&nbsp;value &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;manip(std::cout); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;*this; &nbsp;&nbsp;&nbsp;&nbsp;}};int&nbsp;main(void){ &nbsp;&nbsp;&nbsp;&nbsp;MyStream&nbsp;stream; &nbsp;&nbsp;&nbsp;&nbsp;stream&nbsp;<<&nbsp;10&nbsp;<<&nbsp;"&nbsp;faces."; &nbsp;&nbsp;&nbsp;&nbsp;stream&nbsp;<<&nbsp;MyStream::endl; &nbsp;&nbsp;&nbsp;&nbsp;stream&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}希望这能让您更好地了解这些事情是如何运作的。

白板的微信

问题是这std::endl是一个功能模板,就像你的运营商一样<<&nbsp;。所以当你写:my_stream&nbsp;<<&nbsp;endl;你会希望编译器为运算符推导出模板参数endl。这是不可能的。因此,您必须编写额外的非模板,操作符重载<<以使用操纵器。他们的原型看起来像:UIStream&&nbsp;operator<<(UIStream&&nbsp;os,&nbsp;std::ostream&&nbsp;(*pf)(std::ostream&));(还有另外两个,替换std::ostream为std::basic_ios<char>和&nbsp;std::ios_base,如果你想允许所有的操纵器你也必须提供),它们的实现将与你的模板非常相似。实际上,如此相似,您可以使用您的模板进行实现,如下所示:typedef&nbsp;std::ostream&&nbsp;(*ostream_manipulator)(std::ostream&);UIStream&&nbsp;operator<<(UIStream&&nbsp;os,&nbsp;ostream_manipulator&nbsp;pf){ &nbsp;&nbsp;&nbsp;return&nbsp;operator<<&nbsp;<ostream_manipulator>&nbsp;(os,&nbsp;pf);}最后一点,通常是编写自定义streambuf通常是一种更好的方法来实现应用于您正在使用的技术。
打开App,查看更多内容
随时随地看视频慕课网APP