当重载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 关注
- 988 浏览
添加回答
举报
0/150
提交
取消
