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

标签 c++ operators operator-overloading operator-keyword

ostream 对象之后的任何系统定义的用户类型都转换为字符串或 char* ?

像 cout<<4<<"Hello World";

工作得很好,这是如何实现的? << 运算符是否为每种类型都重载了?有没有办法通过一个通用的重载函数来实现它?我的意思是我可以只有一个带一个参数的重载运算符方法(如 void*),然后在该方法内部决定如何将整数类型转换为 char*

如果我重载运算符 << 使用模板即部分工作

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 不也是一种对象吗?

最佳答案

在重新阅读您的问题后(​​作为此 answer 中的评论的结果)我意识到您想要的不仅是转换为字符串(我在另一个答案中的假设 here ),而是转发进入流的内部。

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

您的问题是转发操纵器(std::hexstd::endl...)。您的 operator<< 被定义为采用类型 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 在这种特殊情况下)

关于c++ - ofstream 或 ostream 类型如何将所有类型转换为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1133739/

相关文章:

python - 什么时候 "i += x"与 Python 中的 "i = i + x"不同?

c++ - friend 功能如何运作

c++ - 带有核心转储的字符串数组(使用模板和运算符重载)

c++ - 指向成员表达式 UB 的指针

c++ - 如何连接字符串和 wstring?

c++ - 检查 vector 中的一组值

java - 小于运算符也评估相等值

c++ - 如何正确重载 + 运算符

c++ - Libevent 仅在第二次 buffer_write 之后写入套接字

c++ - 运算符重载 +=