当运算符<<重载时,std :: endl是未知类型
我重载了operator <<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
工作但是:
my_stream << endl;
给汇编错误:
错误C2678:二进制'<<':找不到操作符找到类型为'UIStream'的左操作数(或者没有可接受的转换)
什么是使my_stream << endl
工作的工作?
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;
}
希望这可以让你更好地了解这些工作。
问题是std::endl
是一个函数模板,因为你的operator <<
是。 所以,当你写:
my_stream << endl;
你会喜欢编译器推导运算符以及endl
的模板参数。 这是不可能的。
所以你必须编写额外的,非模板的operator <<
重载操作符。 他们的原型将如下所示:
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
(还有另外两个,用std::ostream
std::basic_ios<char>
和std::ios_base
替换std::ostream
,如果你想允许所有的操纵器,你也要提供它们),它们的实现将非常类似于你的模板。 事实上,如此相似以至于您可以使用您的模板执行如下操作:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
UIStream& operator<<(UIStream& os, ostream_manipulator pf)
{
return operator<< <ostream_manipulator> (os, pf);
}
最后一点,经常写一个自定义的streambuf
通常是一个更好的方法来实现你尝试应用你正在使用的技术。
我这样做是为了解决我的问题,这里是我的代码的一部分:
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;
}
Main.cpp的
int main(){
CFileLogger log();
log << "[WARNINGS] " << 10 << std::endl;
log << "[ERRORS] " << 2 << std::endl;
...
}
我在这里获得了参考资料http://www.cplusplus.com/forum/general/49590/
希望这可以帮助某人。
链接地址: http://www.djcxy.com/p/73075.html上一篇: std::endl is of unknown type when overloading operator<<
下一篇: ostream operator << in Namespace hides other ostream::operator