- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想创建一个 iostream
适配器类,它允许我即时修改写入流或从流中读取的数据。适配器本身应该是一个 iostream
以允许对第三方代码真正透明。
派生自 std::ostream
的 StreamEncoder
类示例:
// External algorithm, creates large amounts of log data
int foo(int bar, std::ostream& logOutput);
int main()
{
// The target file
std::ofstream file("logfile.lzma");
// A StreamEncoder compressing the output via LZMA
StreamEncoder lzmaEncoder(file, &encodeLzma);
// A StreamEncoder converting the UTF-8 log data to UTF-16
StreamEncoder utf16Encoder(lzmaEncoder, &utf8ToUtf16);
// Call foo(), but write the log data to an LZMA-compressed UTF-16 file
cout << foo(42, utf16Encoder);
}
据我所知,我需要创建一个新的 basic_streambuf
派生并将其嵌入到 basic_ostream
子类中,但这似乎相当复杂。
有没有更简单的方法来完成这个?
最佳答案
奇怪的是,至少当事情真的打算工作时,这些都不应该直接涉及 iostreams 和/或 streambufs。
我会将 iostream 视为媒人类。 iostream 有一个 streambuf,它为某种外部数据源/接收器提供缓冲接口(interface)。它还具有处理所有格式的语言环境。 iostream 只不过是让这两者很好地一起玩(可以这么说)的 playground supervisor。由于您正在处理数据格式化,因此所有这些都(或应该)在语言环境中处理。
尽管语言环境不是单一的——它由许多 facet
组成,每个 facet 专门用于数据格式化的一个特定部分。在这种情况下,您可能关心的部分是 codecvt
方面,它(几乎专门)用于在从 iostream 读取/写入数据的外部和内部表示之间进行转换。
然而,无论好坏,一个语言环境一次只能包含一个 codecvt facet,而不是像您正在考虑的那样包含它们的链。因此,您真正需要/想要的是一个包装类,它提供一个 codecvt 作为其外部接口(interface),但允许您在 I/O 期间链接一些要对数据完成的任意转换集。
对于 utf 到 utf 的转换,Boost.locale 提供了一个 utf_to_utf 函数和 codecvt 包装器代码,因此这部分转换简单明了。
为了避免有人建议用 ICU 来完成这些事情,我要补充一点,Boost.Locale 几乎是 ICU 的包装器,所以这或多或少是相同的答案,但形式对 C++ 更友好(而 ICU 本身更像 Java,并且几乎完全敌视 C++)。
事情的另一面是编写 codecvt facet 给一个相当简单的任务增加了大量的复杂性。过滤 streambuf(例如)通常很多编写起来更简单。它仍然没有您想要的那么容易,但也没有 codecvt 方面那么糟糕。正如@Flexo 已经提到的,Boost iostreams 库已经包含一个过滤 streambuf,它可以进行 zip 压缩。使用 lzma(或 lzh、算术等压缩)做大致相同的事情相对容易,至少假设你有易于使用的压缩函数(你基本上只是为它们提供输入缓冲区,并且它们提供缓冲区结果)。
关于c++ - 创建 std::iostream 适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11493063/
我正在开发一个小型图书馆,我需要做的一件事是让访问者访问一些数据并返回结果。 在一些较旧的 C++ 代码中,访问者需要声明一个 typedef return_type .例如,boost::stati
我正在尝试使用std:map类型的键和值制作std::any Visual Studio 2017 std::map m("lastname", "Ivanov"); std::cout (m["la
我已经在 C++ 的 map 中声明了一个集合为 std::map> .如何循环访问或打印设定值? 最佳答案 如果你知道如何迭代 std::map或 std::set单独地,您应该可以毫无问题地组合迭
如何循环? 我已经试过了: //----- code std::vector >::iterator it; for ( it = users.begin(); it != users.end();
我有两个用例。 A.我想同步访问两个线程的队列。 B.我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。 对于用例 A,我看到了使用 std::lock_
我正在查看这两种类型特征的文档,但不确定有什么区别。我不是语言律师,但据我所知,它们都适用于“memcpy-able”类型。 它们可以互换使用吗? 最佳答案 不,这些术语不能互换使用。这两个术语都表示
我有以下测试代码,其中有一个参数 fS,它是 ofstream 的容器: #include #include #include #include int
这是这个问题的延续 c++ function ptr in unorderer_map, compile time error 我试图使用 std::function 而不是函数指针,并且只有当函数是
std::unordered_map str_bool_map = { {"a", true}, {"b", false}, {"c", true} }; 我们可以在此映射上使
我有以下对象 std::vector> vectorList; 然后我添加到这个使用 std::vector vec_tmp; vec_tmp.push_back(strDRG); vec_tmp.p
为什么 std::initializer_list不支持std::get<> , std::tuple_size和 std::tuple_element ?在constexpr中用得很多现在的表达式,
我有一个像这样定义的变量 auto drum = std::make_tuple ( std::make_tuple ( 0.3f , Ex
假设我有一个私有(private)std::map在我的类(class)里std::map 。我怎样才能将其转换为std::map返回给用户?我想要下面的原型(prototype) const std
假设我有一个私有(private)std::map在我的类(class)里std::map 。我怎样才能将其转换为std::map返回给用户?我想要下面的原型(prototype) const std
问题 我正在尝试将 lambda 闭包传递给 std::thread,它使用任意封闭参数调用任意封闭函数。 template std::thread timed_thread(Function&& f
我想创建一个模板类,可以容纳容器和容器的任意组合。例如,std::vector或 std::map ,例如。 我尝试了很多组合,但我必须承认模板的复杂性让我不知所措。我编译的关闭是这样的: templ
我有一个 std::vector>我将其分配给相同类型的第二个 vector 。 我收到这个编译器错误: /opt/gcc-8.2.0/include/c++/8.2.0/bits/stl_algob
有时候,我们有一个工厂可以生成一个 std::unique_ptr vector ,后来我们想在类/线程/你命名的之间共享这些指针。因此,最好改用 std::shared_ptr 。当然有一种方法可以
这个问题在这里已经有了答案: Sorting a vector of custom objects (14 个答案) 关闭 6 年前。 我创建了一个 vector vector ,我想根据我定义的参
我有三个类(class)成员: public: std::vector > getObjects(); std::vector > getObjects() const; privat
我是一名优秀的程序员,十分优秀!