如何覆盖已定义类型的 ostream <<运算符 如何使下拉子菜单直接显示在其父菜单下方<li>?
How to override ostream << operator for already defined type
我目前正在开发一个现有库的端口,该库使用ostream写入终端。
ostream是作为端口的一部分派生的。
所使用的ostream派生类定义如下:
class owstream: public std::ostream {
public:
CTerminal * output;
giac::context * contextptr;
owstream(CTerminal *, giac::context * contextptr , int = 0);
virtual ~owstream();
};
用于输出一些数据,通常是整数和双精度。
问题是我正在工作的平台有一个错误的双打印例程,导致内核崩溃。
在某些情况下,如果我这样做:
ostream* mystream = new ostream(...);
(*mystream) << 1.23456
大爆炸》
所以,我试图重写<<特定类型的操作符,如:
ostream* GetStream() { return = new MyOStream(...); }
....
ostream* mystream = GetStream()
mystream << 1.23456;
不幸的是,操作符< 我试着把它扩展成这样: 但是这会导致关于操作符<<具有二义性,因为很明显这是一种已经被iostream基类处理过的类型。 我开始怀疑这是否可能。 如何实现<<当给定一个特定的、已经处理的类型时,重写行为的操作符? 目标是能够做一些事情,如: 不崩溃(我显然不会使用cout,但是上面定义的GetStream()可以很好地返回cout)class owstream: public std::ostream {
friend std::ostream& operator<<(std::ostream& out, double val);
public:
CTerminal * output;
giac::context * contextptr;
owstream(CTerminal *, giac::context * contextptr , int = 0);
virtual ~owstream();
};
extern std::ostream& operator<<(std::ostream &out, double val);
cout << 1.234567
我看到你目前的方法/实施有三个问题。
问题# 1
即使您成功地让它使用std::ostream
作为第一个参数并返回值,它也不会正确工作。问题主要是由于超载的operator<<
返回一个ostream
。在第一个值被发送到owstream
之后,所有后续的值都被发送到返回的ostream
。这会让你回到最初问题的起点。为了使其正常工作,您需要将owstream
作为第一个参数,并在重载的operator<<
中返回owstream
。
问题# 2
另一个问题是owstream
可以隐式转换为std::ostream
。根据owstream
在项目中的使用方式,在某些情况下,您提供的重载可能不会产生影响。例如,如果将owstream
类型的对象传递给接受std::ostream
类型的函数,则可能会遇到当前遇到的问题。您可以通过使用private
继承来防止这种情况的发生。这将防止将owstream
隐式地用作std::ostream
。使用private
继承还有一个好处,它可以防止您在不知情的情况下使用std::ostream
中的函数,这可能会导致您回到最初的问题。对于绝对需要std::ostream
的实例,您可以使用访问器函数显式地检索对它的引用。
问题# 3
最后一个问题是std::ostream
包含operator<<
的重载,该重载处理std::ostream
特定的IO操纵符,如std::endl
。如果你没有提供一个重载来专门处理这些,那么std::ostream
中的重载就会被使用,你又回到了开始的地方。如果使用上面描述的private
继承,并且不提供重载来处理操纵符,则编译失败。
<
解决方案/strong>
下面的解决方案类似于JRG提供的解决方案,包括double
、float
和std::ostream
IO操纵符的访问器函数和重载。这是一个完整的工作示例,为了简单起见,它使用了std::cout
中的流缓冲区。我包含了float
的重载,因为有缺陷的库实现可能与它们有类似的问题。它还使用私有继承来防止对std::ostream
的隐式转换。
我在vc++ 10和GCC 4.7.2上测试了它。您可能需要根据编译器和库的兼容性进行一些调整。
#include <ostream>
#include <iostream>
#include <sstream>
class owstream : private std::ostream
{
public:
owstream(std::streambuf* sb)
: std::ostream(sb)
{}
// Template based operator...ohhhhhh ahhhhh.
template <typename T>
friend owstream& operator<<(owstream&, const T&);
// Additional overload to handle ostream specific io manipulators
friend owstream& operator<<(owstream&, std::ostream& (*)(std::ostream&));
// Accessor function to get a reference to the ostream
std::ostream& get_ostream() { return *this; }
};
template <typename T>
inline owstream&
operator<<(owstream& out, const T& value)
{
static_cast<std::ostream&>(out) << value;
return out;
}
// overload for double
template <>
inline owstream&
operator<<(owstream& out, const double& value)
{
std::stringstream ss;
ss << value;
return out << ss.str();
}
// overload for float
template <>
inline owstream&
operator<<(owstream& out, const float& value)
{
std::stringstream ss;
ss << value;
return out << ss.str();
}
// overload for std::ostream specific io manipulators
inline owstream&
operator<<(owstream& out, std::ostream& (*func)(std::ostream&))
{
static_cast<std::ostream&>(out) << func;
return out;
}
int main()
{
owstream ows(std::cout.rdbuf());
ows << std::endl;
ows << "hello " << 1.0 << " " << 2.0f << std::endl;
}
这样怎么样:
template <typename T>
owstream& operator<<(owstream&, const T&);
template <typename T>
inline owstream&
operator<<(owstream& os, const T& val)
{
std::ostream& stdos = static_cast<std::ostream&>(os);
stdos << val;
return os;
}
template <>
inline owstream&
operator<<(owstream& os, const double& val)
{
std::stringstream ss;
ss << val;
os << ss.str();
return os;
}
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 无法获取菜单选择以运行函数.C++
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- C++ 中的图形菜单
- C++ 程序菜单使用做同时和切换
- 我正在尝试创建一个菜单,但我的代码一直在循环
- 触发另一个窗口的菜单按钮
- 从子菜单返回后,正确的输入至少进入验证循环一次
- C++ 我的开关格式中的循环不允许我显示菜单选项或接受输入?
- 如何为我的游戏设置主菜单场景?QT C++
- C++循环菜单时做
- 难以从 CImageList 设置菜单项位图
- 如何将我的程序添加到文件和文件夹的macOS右键单击菜单?
- 如何以编程方式显示功能区按钮的下拉菜单?
- 如何在win32的窗口类中设置动态菜单?
- 为什么我的 Do-while 循环无法在C++中运行菜单
- 我正在尝试用 c++ 制作菜单,但不明白为什么它不循环
- 如何使用IExecuteCommand和动词在上下文菜单外壳扩展中显示本地化文本和自定义图标?