ofstream 或 ostream 类型如何将所有类型转换为字符串?

发布于 2024-07-26 21:47:08 字数 758 浏览 3 评论 0原文

过去到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

且行且努力 2024-08-02 21:47:10

我只有一个重载运算符
具有一个参数的方法(如 void*)
然后在该方法中决定如何
将整数类型转换为 char*

不,你不能。 void * 不携带类型信息,因此无法确定它实际指向的类型。

an i have just one overloaded operator
method with one parameter(like void*)
and then decide inside that method how
to typecast integer to char*

No, you can't. A void * carries no type information, so there is no way of working out what type it actually points to.

高跟鞋的旋律 2024-08-02 21:47:10

只有一个重载函数。 它不需要 void *,因为那是无用的。 如果它采用一种数据类型,则它不会重载,并且只会在转换为该类型后看到输入值。 这意味着您无法控制如何转换,例如 int

如果您希望在 intchar * 之间有不同的行为,您需要让函数以某种方式知道它正在获取什么类型,并且需要传递值。这正是重载函数或模板函数的作用。

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, an int.

If you want different behavior between, say, an int and a char *, 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.

薆情海 2024-08-02 21:47:10

是<< 每种类型的运算符都重载了吗?

是的

有没有一种方法可以通过一个通用重载函数来实现它?

这个问题没有意义..您只想要一个函数,还是想要一个重载函数?

is the << operator overloaded for each and every type?

yes

is there a way to achieve it through just one generic overloaded function?

this question doesn't make sense .. do you want just one function, or do you want an overloaded function?

岛徒 2024-08-02 21:47:09

重新阅读您的问题后(​​由于此 答案)我意识到你想要的不仅仅是转换成字符串(我在另一个答案中的假设此处),而是转发到内部 ofstream。

现在,你想要实现的目标并不简单,而且在大多数情况下可能是矫枉过正。 在我拥有的 [make_string][3] 实现中(转发到内部 ostringstream),我不允许传递操纵器。 如果用户想要添加新行(我们在linux下开发),他们只需传递一个'\n'字符。

您的问题是转发操纵器(std::hexstd::endl...)。 您的运营商<< 被定义为采用类型 T 的常量实例,但操纵器是函数指针,编译器无法将其与您的方法进行匹配。

操纵器是在 std::basic_ostream 模板上运行的函数。 basic_ostream 模板和 ostream 类定义为:

template <typename TChar, typename TTraits = char_traits<TChar> >
class basic_ostream;

typedef basic_ostream<char> ostream;
// or
// typedef basic_ostream<wchar_t> if using wide characters

那么可以传递给 std::ostream 的可能的操纵器是:

typedef std::ostream& (*manip1)( std::ostream& );

typedef std::basic_ios< std::ostream::char_type, std::ostream::traits_type > ios_type;
typedef ios_type& (*manip2)( ios_type& );

typedef std::ios_base& (*manip3)( std::ios_base& );

如果您想接受操纵器,则必须提供该操纵器类中的重载:

class mystream
{
//...
public:
   template <typename T> 
   mystream& operator<<( T datum ) {
      stream << datum;
      return *this
   }
   // overload for manipulators
   mystream& operator<<( manip1 fp ) {
      stream << fp;
      return *this;
   }
   mystream& operator<<( manip2 fp ) {
      stream << fp;
      return *this;
   }
   mystream& operator<<( manip3 fp ) {
      stream << fp;
      return *this;
   }
};

特别是,endl 的签名(可能是您唯一需要的)是:

template <typename Char, typename Traits>
std::basic_ostream<Char,Traits>& 
   std::endl( std::basic_ostream<Char,Traits>& stream );

所以它属于 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 internal ostringstream), 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. The basic_ostream template and ostream class are defined as:

template <typename TChar, typename TTraits = char_traits<TChar> >
class basic_ostream;

typedef basic_ostream<char> ostream;
// or
// typedef basic_ostream<wchar_t> if using wide characters

Then the possible manipulators that can be passed to a std::ostream are:

typedef std::ostream& (*manip1)( std::ostream& );

typedef std::basic_ios< std::ostream::char_type, std::ostream::traits_type > ios_type;
typedef ios_type& (*manip2)( ios_type& );

typedef std::ios_base& (*manip3)( std::ios_base& );

If you want to accept manipulators you must provide that overload in your class:

class mystream
{
//...
public:
   template <typename T> 
   mystream& operator<<( T datum ) {
      stream << datum;
      return *this
   }
   // overload for manipulators
   mystream& operator<<( manip1 fp ) {
      stream << fp;
      return *this;
   }
   mystream& operator<<( manip2 fp ) {
      stream << fp;
      return *this;
   }
   mystream& operator<<( manip3 fp ) {
      stream << fp;
      return *this;
   }
};

In particular, the signature for endl (which may be the only one you require) is:

template <typename Char, typename Traits>
std::basic_ostream<Char,Traits>& 
   std::endl( std::basic_ostream<Char,Traits>& stream );

so it falls under the manip1 type of functions. Others, like std::hex fall under different categories (manip3 in this particular case)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文