当重载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工作的工作是什么?
3 回答
汪汪一只猫
TA贡献1898条经验 获得超8个赞
std::endl
是一个函数,std::cout
通过实现operator<<
获取具有相同签名的函数指针来利用它std::endl
。
在那里,它调用函数,并转发返回值。
这是一个代码示例:
#include <iostream>struct MyStream{ template <typename T> MyStream& operator<<(const T& x) { std::cout << x; return *this; } // function that takes a custom stream, and returns it typedef MyStream& (*MyStreamManipulator)(MyStream&); // take in a function with the custom signature MyStream& operator<<(MyStreamManipulator manip) { // call the function, and return it's value return manip(*this); } // define the custom endl for this stream. // note how it matches the `MyStreamManipulator` // function signature static MyStream& endl(MyStream& stream) { // print a new line std::cout << std::endl; // do other stuff with the stream // std::cout, for example, will flush the stream stream << "Called MyStream::endl!" << std::endl; return stream; } // this is the type of std::cout typedef std::basic_ostream<char, std::char_traits<char> > CoutType; // this is the function signature of std::endl typedef CoutType& (*StandardEndLine)(CoutType&); // define an operator<< to take in std::endl MyStream& operator<<(StandardEndLine manip) { // call the function, but we cannot return it's value manip(std::cout); return *this; }};int main(void){ MyStream stream; stream << 10 << " faces."; stream << MyStream::endl; stream << std::endl; return 0;}
希望这能让您更好地了解这些事情是如何运作的。
白板的微信
TA贡献1883条经验 获得超3个赞
问题是这std::endl
是一个功能模板,就像你的运营商一样<<
。所以当你写:
my_stream << endl;
你会希望编译器为运算符推导出模板参数endl
。这是不可能的。
因此,您必须编写额外的非模板,操作符重载<<
以使用操纵器。他们的原型看起来像:
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
(还有另外两个,替换std::ostream
为std::basic_ios<char>
和 std::ios_base
,如果你想允许所有的操纵器你也必须提供),它们的实现将与你的模板非常相似。实际上,如此相似,您可以使用您的模板进行实现,如下所示:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);UIStream& operator<<(UIStream& os, ostream_manipulator pf){ return operator<< <ostream_manipulator> (os, pf);}
最后一点,通常是编写自定义streambuf
通常是一种更好的方法来实现应用于您正在使用的技术。
- 3 回答
- 0 关注
- 930 浏览
添加回答
举报
0/150
提交
取消