操作员过载<<带basic_ostream
Overload of operator<< with basic_ostream
为什么使用用户定义的类C
进行流操作的典型标头通常是这样的:
std::ostream& operator<<(std::ostream& os, const C& c);
std::istream& operator>>(std::istream& is, C&);
而不是这样的:
template <class CharT, class Traits>
std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os
const C& c);
template <class CharT, class Traits>
std::basic_istream<CharT, Traits>& operator>>(
std::basic_istream<CharT, Traits>& is
C& c);
我的问题是为什么流运算符的通常重载是用std::ostream
完成的,这是一个用于std::basic_ostream
char
的typedef,为什么不直接用std::basic_ostream
完成?
例如:
class C
{
...
};
std::ostream& operator<<(std::ostream& os, const C& c)
{
...
}
int main()
{
C c;
std::wofstream myFile("myFile.txt");
myFile << c; //Impossible
}
这里写的operator<<
限制我们只能使用专门用于char
的流对象(std::ostream
、std::ostringstream
、...(。因此,如果使用std::ostream
比std::basic_ostream
更具限制性,为什么在谈论流运算符重载时从未提及std::basic_ostream
?
实际上,使用两种不同的字符类型:
- Windows使用
wchar_t
是Unicode人很久以前做出的承诺的结果(Unicode将只使用16位,每个字符将仅包含一个单元(,并且此后一直被打破。 - 其他人都使用
char
现在主要被认为是 UTF-8 编码中的一个字节(显然,不是通用的(。
回想起来,引入wchar_t
(甚至更何况char16_t
和char32_t
(是不明智的,如果只使用char
,世界会变得更好。因此,那些不受Windows困扰的人并不关心wchar_t
版本的I/O操作,而Windows通常似乎在IOStreams上打赌(众所周知,MSVC++实现很慢,并且没有打算对此做任何事情(。
另一个原因是,编写模板化的 I/O 运算符被认为增加了已经复杂的系统的复杂性。似乎很少有人了解 IOStreams,在这少数人中,对支持多种字符类型感兴趣的人更少。
模板化 I/O 运算符感知复杂性的一个方面是假设实现需要进入标头,当然,这是不正确的,因为基本上只有两种字符类型是 IOStreams 实例化(char
和 wchar_t
(: 尽管 IOStreams 可以用其他字符类型实例化, 我很确定几乎没有人真正这样做。虽然我知道这需要什么,但我可能仍然需要至少一天的时间来定义所有必要的方面。因此,模板定义可以在合适的翻译单元中定义并在那里实例化。或者,不是定义运算符是模板,而是可以完全专业化。
独立于如何定义模板化运算符,通常工作量更大。如果天真地完成(即直接使用例如std::ctype<cT>
(,结果会很慢,当做得正确时(即,从std::ctype<cT>
缓存结果(,它将非常复杂。
综合起来:何必呢?
如果我必须写入std::wostream
或从std::wistream
读取,我实际上会创建一个过滤流缓冲区,它只是使用合适的std::codecvt<...>
方面(甚至只是使用std::ctype<wchar_t>
的widen()
或narrow()
(来转换写入/读取的字符。它不会处理字符串的正确国际化,但无论如何,std::locale
设施都无法真正达到适当的国际化(为此您需要像 ICU 这样的东西(。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- ostream过载时的缓冲区冲洗
- 需要从 istream 和 ostream 派生 iostream
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- "ostream &os"有什么用?
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 我的运算符重载是否有效<<(流插入)左操作数不是 ostream
- C++表达SFINAE和ostream操纵器
- 在抛出 'std::runtime_error' 的实例后终止调用 what(): Filebuf 和 ostream 的 I/O 错误
- oStream 不打印添加两个 valarray 的结果(使用运算符重载)
- C++运算符<<调用::ostream而不是std::osttream
- BOOST ::变体无法解决运算符&lt;&lt;对于STD :: Ostream
- C++ostream:没有运算符匹配<<&应在'&'代币
- 重载运算符<<用于ostream语法
- 重载ostream&时转换错误无效;operator< & lt;
- 运算符<<(ostream&os,..)用于模板类
- std::ostream&operator< & lt; (std:: ostream&压力,压力& &;val)
- 上Ostream & lt; & lt;重载的困惑