Kaz*_*oom 58 c++ stl operator-overloading
我重载了运算符<<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
Run Code Online (Sandbox Code Playgroud)
工作但是:
my_stream << endl;
Run Code Online (Sandbox Code Playgroud)
给出编译错误:
错误C2678:二进制'<<':找不到哪个运算符带有'UIStream'类型的左操作数(或者没有可接受的转换)
做my_stream << endl工作的工作是什么?
GMa*_*ckG 81
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;
}
Run Code Online (Sandbox Code Playgroud)
希望这能让您更好地了解这些事情是如何运作的.
APr*_*mer 36
问题是这std::endl是一个功能模板,就像你的运营商一样<<
.所以当你写:
my_stream << endl;
Run Code Online (Sandbox Code Playgroud)
你会希望编译器为运算符推导出模板参数endl.这是不可能的.
因此,您必须编写额外的非模板,操作符重载<<以使用操纵器.他们的原型看起来像:
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
Run Code Online (Sandbox Code Playgroud)
(还有另外两个,替换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);
}
Run Code Online (Sandbox Code Playgroud)
最后一点,通常是编写自定义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;
}
Run Code Online (Sandbox Code Playgroud)
Main.cpp的
int main(){
CFileLogger log();
log << "[WARNINGS] " << 10 << std::endl;
log << "[ERRORS] " << 2 << std::endl;
...
}
Run Code Online (Sandbox Code Playgroud)
我在这里得到了参考资料http://www.cplusplus.com/forum/general/49590/
希望这可以帮助别人.
| 归档时间: |
|
| 查看次数: |
21317 次 |
| 最近记录: |