gpt4 book ai didi

c++ - 使用内部 vector 成员创建类作为流访问类实例的容器

转载 作者:行者123 更新时间:2023-11-30 05:31:59 25 4
gpt4 key购买 nike

提前感谢任何愿意看这个的人的时间。

我想制作一个允许所有流接口(interface)的简单类,但只读/写存储在类中的简单 std::vector。在我尝试自己重写所有内容,然后尝试从 basic_stream 派生之后,在我看来,使用 boost::iostreams 可以最大限度地减少我需要重写的代码量。例如:这是我想做的,但我希望我的类像 os 一样被使用(因此我尝试从 boost::iostreams::stream 派生):http://theboostcpplibraries.com/boost.iostreams-devices

这是一个“第一次尝试”,其中我尝试继承stream和stream_buffer(不知道是否需要)。我只想让流运算符(operator)都使用 std::vector<char>数据作为容器。

//File: memfile2.h
#pragma once

#include <algorithm> // copy, min
#include <iosfwd> // streamsize
#include <boost/iostreams/categories.hpp> // source_tag
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/stream_buffer.hpp>

//REV: use boost iostreams to let user write to a local vector of chars
//as a memory file.

//REV: Or just "get" one from the pointer, i.e. have a mem_ptr which "opens" a file.


struct mfile : public boost::iostreams::stream<boost::iostreams::array_source>, boost::iostreams::stream_buffer
{
std::vector<char> data;

mfile()
: boost::iostreams::stream<boost::iostreams::array_source>( data ),
boost::iostreams::stream_buffer()
{
}

void other_funct()
{
}
};

一个示例使用程序是:

#include <memfile2.h>

int main()
{
mfile f;

f << "YOLO";

std::string fromf;
//f.seekg(0, BOOST_IOS::beg);
f >> fromf;
fprintf(stdout, "OUTPUT: [%s]\n", fromf.c_str());

f.other_funct();
}

最佳答案

以下是三个片段:

继承,非常通用

Live On Coliru

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <iostream>
#include <iomanip>
#include <fstream>

template <typename CharT = char, typename CharTraits = std::char_traits<CharT>,
typename Buffer = std::vector<CharT>,
typename Base = boost::iostreams::stream<boost::iostreams::back_insert_device<Buffer> >
>
struct basic_fixed_stream : private Buffer, public Base {
basic_fixed_stream() : Buffer(), Base(*static_cast<Buffer*>(this)) {}

std::string to_string() const {
flush(*this);
return { Buffer::begin(), Buffer::end() };
}
};

using fixed_stream = basic_fixed_stream<char>;

int main()
{

fixed_stream f;
f << "YOLO " << std::showbase << std::hex << std::setfill('0') << 42;

std::string fromf = f.to_string();
fprintf(stdout, "OUTPUT: [%s]\n", fromf.c_str());
}

打印:

OUTPUT: [YOLO 0x2a]

更简单,没有继承

Live On Coliru

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <iostream>
#include <iomanip>
#include <fstream>

struct fixed_stream {
template <typename OS=std::ostream> friend fixed_stream& operator<<(fixed_stream& os, OS&(*manip)(OS&)) {
os._stream << manip;
return os;
}

template <typename T> friend fixed_stream& operator<<(fixed_stream& os, T const& v) {
os._stream << v;
return os;
}
std::string to_string() const {
flush(_stream);
return { _buffer.begin(), _buffer.end() };
}

operator std::ostream&() { return _stream; }
private:
using buffer_t = std::vector<char>;
buffer_t _buffer;
boost::iostreams::stream<boost::iostreams::back_insert_device<buffer_t> > _stream { _buffer };
};

int main()
{
fixed_stream f;
f << "YOLO " << std::showbase << std::hex << std::setfill('0') << 42;

std::string fromf = f.to_string();
fprintf(stdout, "OUTPUT: [%s]\n", fromf.c_str());
}

同样的输出:

OUTPUT: [YOLO 0x2a]

双向:

另一个也有 istream 功能。请注意,这修复了容量(为方便起见):

Note, if you push more than capacity input, the stream state goes bad. You will want to handle errors and/or clear() the state.

Live On Coliru

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/array.hpp>
#include <iostream>
#include <iomanip>
#include <fstream>

template <typename CharT = char, typename CharTraits = std::char_traits<CharT>,
typename Buffer = std::vector<CharT>,
typename Base = boost::iostreams::stream<boost::iostreams::array>
>
struct basic_fixed_stream : private Buffer, public Base {
basic_fixed_stream(size_t capacity = 1024) : Buffer(capacity), Base(this->data(), this->size()) {}

using Base::clear;

std::string to_string() const {
flush(*this);
return { Buffer::begin(), Buffer::end() };
}
};

using fixed_stream = basic_fixed_stream<char>;

int main()
{
{
fixed_stream f;
f << "YOLO " << std::showbase << std::hex << std::setfill('0') << 42;

std::string fromf = f.to_string();
fprintf(stdout, "OUTPUT: [%s]\n", fromf.c_str());
}

{
fixed_stream f;
{
std::ifstream ifs("main.cpp");
f << ifs.rdbuf();
}
f.clear();
f.seekg(0);

std::string line;
while (getline(f, line))
fprintf(stdout, "OUTPUT: [%s]\n", line.c_str());
}


}

输出:

OUTPUT: [YOLO 0x2a]
OUTPUT: [#include <iostream>]
OUTPUT: [#include <boost/spirit/home/x3.hpp>]
OUTPUT: [#include <boost/fusion/adapted/std_tuple.hpp>]
OUTPUT: [#include <boost/spirit/home/x3/binary.hpp>]
OUTPUT: []
OUTPUT: [namespace x3 = boost::spirit::x3;]
OUTPUT: []
OUTPUT: [namespace hessian {]
OUTPUT: []
OUTPUT: [ typedef std::string string_t;]
OUTPUT: []
OUTPUT: [ namespace parser {]
OUTPUT: []
OUTPUT: [ struct bstring : x3::parser<bstring> {]
OUTPUT: [ using attribute_type = hessian::string_t;]
OUTPUT: []
OUTPUT: [ // string ::= s b1 b0 <utf8-data> string]
OUTPUT: [ // ::= S b1 b0 <utf8-data>]
OUTPUT: [ // ::= [x00-x1f] <utf8-data>]
OUTPUT: [ // NOTE: The length means number of UTF16 characters but the content is given in UTF8 characters!]
OUTPUT: [ template <typename It, typename Ctx, typename Attr>]
OUTPUT: [ bool parse(It& f, It const& l, Ctx&, x3::unused_type, Attr& attr) const {]
OUTPUT: [ auto saved = f;]
OUTPUT: [ char type;]
OUTPUT: [ size_t len;]
OUTPUT: [ auto tied = std::tie(type, len);]
OUTPUT: []
OUTPUT: [ while (x3::parse(f,l,x3::char_("sS") >> x3::big_word,tied)) {]
OUTPUT: [ ]

您会注意到这是源代码的第一个千字节!

关于c++ - 使用内部 vector 成员创建类作为流访问类实例的容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35337612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com