ofstream 或 ostream 类型如何将所有类型转换为字符串?
过去到 ostream 对象的任何系统定义的用户类型都会转换为字符串或 char* 吗?
就像 cout<<4<<"Hello World";
工作得很好,这是如何实现的? 是 << 每种类型的运算符都重载了吗? 有没有一种方法可以通过一个通用重载函数来实现它? 我的意思是,我是否可以只有一个带有一个参数的重载运算符方法(例如 void*),然后在该方法内部决定如何将整数类型转换为 char*
如果我重载运算符 << ,那么事情会部分起作用。 使用模板 ie
class UIStream
{
private:
ofstream stream;
public:
UIStream();
~UIStream();
template <typename T>
UIStream& operator << (const T);
};
所以这可以工作
UIStream my_stream;
my_stream<<"bcd"<10;
时,它会给出编译器错误
my_stream <<endl;
,但是当我执行此错误 C2678:二进制 '<<' :找不到采用“UIStream”类型的左操作数的运算符(或者没有可接受的转换)
std::endl 不是也是一种对象类型吗?
any system defined user type past to ostream object is converted to a string or char* ?
like cout<<4<<"Hello World";
works perfectly fine, how is this achieved? is the << operator overloaded for each and every type? is there a way to achieve it through just one generic overloaded function? what i mean is can i have just one overloaded operator method with one parameter(like void*) and then decide inside that method how to typecast integer to char*
Things worked partially if i overload operator << using Template i.e
class UIStream
{
private:
ofstream stream;
public:
UIStream();
~UIStream();
template <typename T>
UIStream& operator << (const T);
};
so this works
UIStream my_stream;
my_stream<<"bcd"<10;
however it gives compiler error when i do this
my_stream <<endl;
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'UIStream' (or there is no acceptable conversion)
Is not std::endl a type of object too?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,你不能。 void * 不携带类型信息,因此无法确定它实际指向的类型。
No, you can't. A void * carries no type information, so there is no way of working out what type it actually points to.
只有一个重载函数。 它不需要
void *
,因为那是无用的。 如果它采用一种数据类型,则它不会重载,并且只会在转换为该类型后看到输入值。 这意味着您无法控制如何转换,例如int
。如果您希望在
int
和char *
之间有不同的行为,您需要让函数以某种方式知道它正在获取什么类型,并且需要传递值。这正是重载函数或模板函数的作用。There is just one overloaded function. It doesn't take a
void *
, because that would be useless. If it takes one data type, it isn't overloaded, and it only sees the input value after it's been converted to the type. That means you have no control over how to convert, say, anint
.If you want different behavior between, say, an
int
and achar *
, you need to let the function know somehow what type it is getting, and you need to pass the value in. This is exactly what an overloaded or template function does.是的
这个问题没有意义..您只想要一个函数,还是想要一个重载函数?
yes
this question doesn't make sense .. do you want just one function, or do you want an overloaded function?
重新阅读您的问题后(由于此 答案)我意识到你想要的不仅仅是转换成字符串(我在另一个答案中的假设此处),而是转发到内部 ofstream。
现在,你想要实现的目标并不简单,而且在大多数情况下可能是矫枉过正。 在我拥有的
[make_string][3]
实现中(转发到内部ostringstream
),我不允许传递操纵器。 如果用户想要添加新行(我们在linux下开发),他们只需传递一个'\n'字符。您的问题是转发操纵器(
std::hex
、std::endl
...)。 您的运营商<< 被定义为采用类型 T 的常量实例,但操纵器是函数指针,编译器无法将其与您的方法进行匹配。操纵器是在
std::basic_ostream
模板上运行的函数。basic_ostream
模板和ostream
类定义为:那么可以传递给 std::ostream 的可能的操纵器是:
如果您想接受操纵器,则必须提供该操纵器类中的重载:
特别是,endl 的签名(可能是您唯一需要的)是:
所以它属于
manip1
函数类型。 其他的,例如std::hex
属于不同的类别(在本例中为manip3
)After re-reading your question (as a result of a comment in this answer) I have realized that what you want is not only conversions into string (my assumptions in the other answer here), but rather forwarding into the internal ofstream.
Now, what you want to achieve is not simple, and may be overkill in most cases. In the implementation of
[make_string][3]
that I have (that forwards to an internalostringstream
), I don't allow for manipulators to be passed. If the user wants to add a new line (we develop under linux) they just pass a '\n' character.Your problem is forwarding manipulators (
std::hex
,std::endl
...). Your operator<< is defined as taking a constant instance of a type T, but manipulators are function pointers and the compiler is not able to match it against your methods.Manipulators are functions that operate on the
std::basic_ostream
template. Thebasic_ostream
template andostream
class are defined as:Then the possible manipulators that can be passed to a std::ostream are:
If you want to accept manipulators you must provide that overload in your class:
In particular, the signature for endl (which may be the only one you require) is:
so it falls under the
manip1
type of functions. Others, likestd::hex
fall under different categories (manip3
in this particular case)