为什么使用用户定义的类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
来完成流操作符的重载,这是char
std::basic_ostream
的typedef,以及为什么不直接使用{{1}完成}
例如:
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
从未被提及?
答案 0 :(得分:2)
实际上,使用了两种不同的字符类型:
wchar_t
作为很久以前Unicode人员做出的承诺的结果(Unicode只使用16位,每个字符只包含一个单元),并且自那时起就被破坏了。 char
,现在大多数人认为它是UTF-8编码中的一个字节(显然,不是普遍的)。回想起来,wchar_t
(尤其是char16_t
和char32_t
)的引入是不明智的,只有char
才会让世界变得更好会被使用。因此,那些不受Windows困扰的人并不关心I / O操作的wchar_t
版本,而Windows一般似乎都在IOStreams上运行(已知MSVC ++实现很慢,对此没有任何意图)。
另一个原因是,编写模板化I / O运算符会增加已经复杂系统的复杂性。很少有人能够理解IOStreams,而在这些人中,更少有人对支持多种角色类型感兴趣。
通过模板化I / O运算符感知复杂性的一个方面是假设实现需要进入标题,当然,这不是正确的,因为基本上只有两个字符类型IOStream实例化({ {1}}和char
):虽然IOStreams 可以用其他字符类型实例化,但我很确定几乎没有人真正这样做过。虽然我知道它需要什么,但我可能仍需要至少一天来定义所有必要的方面。因此,模板定义可以在合适的翻译单元中定义并在那里实例化。或者,不是定义运算符是模板,而是完全专门化。
独立于如何定义模板化运算符,通常更多的工作。如果天真地完成(即,直接使用例如wchar_t
),结果将是缓慢的,并且当正确地执行时(即,来自std::ctype<cT>
的缓存结果),它将非常复杂。
把它们放在一起:为什么要这么麻烦?
如果我必须写信至std::ctype<cT>
或从std::wostream
读取,我实际创建了一个过滤流缓冲区,它只是使用合适的std::wistream
来翻译写入/读取的字符facet(甚至只使用std::codecvt<...>
&#39; s std::ctype<wchar_t>
或widen()
)。它不会处理字符串的正确国际化,但narrow()
设施无论如何都不适合国际化(你需要ICU之类的东西)。< / p>