从 std::istreambuf_iterator<> 复制到 std::vector<>

发布于 2024-09-02 13:46:46 字数 1613 浏览 6 评论 0 原文

我有一个 Visual Studio 2008 C++ 应用程序,我想将流视为一组迭代器。

例如,如果我要通过流接收 WIN32_FIND_DATA 结构数组,我希望能够执行以下操作:

IStreamBuf< WIN32_FIND_DATA > sb( stream );
std::vector< WIN32_FIND_DATA > buffer;
std::copy( std::istreambuf_iterator< WIN32_FIND_DATA >( &sb ), 
           std::istreambuf_iterator< WIN32_FIND_DATA >(),
           std::back_inserter( buffer ) );

为了实现此目的,我定义了一个派生自 std::basic_streambuf<> 的类;:

template< typename T >
class IStreamBuf : public std::basic_streambuf< byte >
{
public:

    IStreamBuf( IStream* stream ) : stream_( stream )
    {        
    };

protected:

    virtual traits_type::int_type underflow()
    {
        DWORD bytes_read = 0;
        HRESULT hr = stream_->Read( &buffer_, sizeof( T ), &bytes_read );
        if( FAILED( hr ) )
            return traits_type::eof();

        traits_type::char_type* begin = 
            reinterpret_cast< traits_type::char_type* >( &buffer_ );
        setg( begin, begin, begin + bytes_read );   
        return traits_type::to_int_type( *gptr() );
    };

private:

    // buffer to hold current item of type T
    T buffer_;

    // stream used to receive data
    IStream* stream_;
}; // class IStreamBuf

我不知道如何优雅地从 byte 数组转换为 WIN32_FIND_DATA 数组。因为 std::basic_streambuf<> 需要 std::char_traits<> 模板参数,所以我的印象是它只能使用内置类型,例如charbyte,而不是像 WIN32_FIND_DATA 这样的结构。正确的?

关于如何开展这项工作有什么建议吗?

谢谢, 保罗·H

I have a Visual Studio 2008 C++ application where I would like to treat a stream as a set of iterators.

For example, if I were to receive an array of WIN32_FIND_DATA structures over the stream, I would like to be able to do something like this:

IStreamBuf< WIN32_FIND_DATA > sb( stream );
std::vector< WIN32_FIND_DATA > buffer;
std::copy( std::istreambuf_iterator< WIN32_FIND_DATA >( &sb ), 
           std::istreambuf_iterator< WIN32_FIND_DATA >(),
           std::back_inserter( buffer ) );

To accomplish this, I've defined a class derived from std::basic_streambuf<>:

template< typename T >
class IStreamBuf : public std::basic_streambuf< byte >
{
public:

    IStreamBuf( IStream* stream ) : stream_( stream )
    {        
    };

protected:

    virtual traits_type::int_type underflow()
    {
        DWORD bytes_read = 0;
        HRESULT hr = stream_->Read( &buffer_, sizeof( T ), &bytes_read );
        if( FAILED( hr ) )
            return traits_type::eof();

        traits_type::char_type* begin = 
            reinterpret_cast< traits_type::char_type* >( &buffer_ );
        setg( begin, begin, begin + bytes_read );   
        return traits_type::to_int_type( *gptr() );
    };

private:

    // buffer to hold current item of type T
    T buffer_;

    // stream used to receive data
    IStream* stream_;
}; // class IStreamBuf

What I can't figure out is how to gracefully go from an array of bytes to an array of WIN32_FIND_DATAs. Because std::basic_streambuf<> requires a std::char_traits<> template parameter, I'm under the impression that it can only use built-in types like char or byte, not a structure like WIN32_FIND_DATA. Correct?

Any suggestions on how to make this work?

Thanks,
PaulH

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪化雨蝶 2024-09-09 13:46:46

istreambuf_iterator 在缓冲区级别工作,它只是一个字节流。如果您想处理结构,您可能需要使用 istream_iterator 来代替,并创建一个 operator>> 来读取 WIN32_FIND_DATA 结构。您还可以考虑为 WIN32_FIND_DATA 创建/使用代理。

An istreambuf_iterator works at the buffer level, where it's just a stream of bytes. If you want to deal with structures, you probably want to use an istream_iterator instead, and create an operator>> to read the WIN32_FIND_DATA structures. You might also consider creating/using a proxy for the WIN32_FIND_DATA.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文