std::endl is of unknown type when overloading operator<<
我操作人员超载<<
1 2 3 4 5 | template <Typename T> UIStream& operator<<(const T); UIStream my_stream; my_stream << 10 <<" heads"; |
但工作:
1 | my_stream << endl; |
给出编译错误:
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'UIStream' (or there is no acceptable conversion)
使
在这里,它调用函数,并转发返回值。
下面是一个代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #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; } |
希望这能让你更好地了解这些东西是如何工作的。
问题是,
1 | my_stream << endl; |
您希望编译器为运算符推导模板参数以及用于
因此,您必须编写额外的、非模板的、运算符
1 | UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&)); |
(还有两个,用
1 2 3 4 5 | typedef std::ostream& (*ostream_manipulator)(std::ostream&); UIStream& operator<<(UIStream& os, ostream_manipulator pf) { return operator<< <ostream_manipulator> (os, pf); } |
最后一个注释,通常是写一个自定义的
我这样做是为了解决我的问题,下面是我的代码的一部分:
1 2 3 4 5 6 7 8 9 10 11 | template<typename T> CFileLogger &operator <<(const T value) { (*this).logFile << value; return *this; } CFileLogger &operator <<(std::ostream& (*os)(std::ostream&)) { (*this).logFile << os; return *this; } |
主CPP
1 2 3 4 5 6 7 | int main(){ CFileLogger log(); log <<"[WARNINGS]" << 10 << std::endl; log <<"[ERRORS]" << 2 << std::endl; ... } |
我在这里找到了参考资料http://www.cplusplus.com/forum/general/49590/
希望这能帮助别人。
有关扩展iostream的更好方法,请参阅此处。(有点过时了,而且是为VC 6量身定做的,所以你得带上一粒盐)
要点是,要使函数正常工作(endl,它同时输出""和flushes是一个函数),需要实现完整的ostream接口。
要使
1 | UStream& operator<<( UStream&, UStream& (*f)( UStream& ) ); |
或
1 | UStream& UStream::operator<<( UStream& (*f)( UStream& ) ); |
现在,
编辑:看起来像GMAN的答案更好。他也让
除了接受的答案之外,用C++ 11可以为类型过载EDOCX1×2Ω。
1 | decltype(std::endl<char, std::char_traits<char>>) |