代码之家  ›  专栏  ›  技术社区  ›  tangy

模拟流进行测试

  •  0
  • tangy  · 技术社区  · 7 年前

    Get an istream from a char*

    struct mock_membuf : std::streambuf
    {
        mock_membuf(char* begin, char* end) {
            this->setg(begin, begin, end);
        }
    };
    
    struct MockStreamContainer{
        explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}
    
        std::istream& Body() const {
            return m_body;
        }
    
        int Size() const {
            return m_size;
        }
    
        mock_membuf m_sbuf; // same as membuf from the question referenced
        std::istream& m_body;
        int64_t m_size;
    };
    

    并将按如下方式使用:

    int main()
    {
        char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";
    
        auto get_stream = [&buffer](int offset, int nbytes) {
            return MockStreamContainer(buffer, offset, nbytes);
        };
        std::string line;
        auto r = get_stream(5, 10);
        std::istream& in = r.Body();
        while (std::getline(in, line)) {
            std::cout << "line: " << line << "\n";
        }
        return 0;
    }
    

    link )是否错误百出——关于如何正确有效地实施这一点,有什么建议吗?

    注意:根据要求,上述代码当前抛出以下编译错误:

    main.cpp: In constructor 'MockStreamContainer::MockStreamContainer(char*, int, int)':
    
    main.cpp:17:131: error: invalid initialization of non-const reference of type 'std::istream&' {aka 'std::basic_istream<char>&'} from an rvalue of type 'mock_membuf*'
    
         explicit MockStreamContainer(char* buffer, int offset, int nbytes): m_sbuf(buffer + offset, buffer + offset + nbytes), m_body(&m_sbuf), m_size(nbytes) {}
    

    1 回复  |  直到 7 年前
        1
  •  1
  •   Loki Astari    7 年前

    您的成员变量m_body是一个引用:

    std::istream&    m_body;
                ^     reference
    

    explicit MockStreamContainer(char* buffer, int offset, int nbytes):
        m_sbuf(buffer + offset, buffer + offset + nbytes),
        m_body(&m_sbuf),    // Here you are passing a pointer to `std::streambuf`
                            // This is not an `std::istream` so the compiler
                            // is trying to create one using the single argument
                            // constructor.
                            //
                            // That worked. So you have a temporary `std::istream` object
                            //
                            // You can not bind a temporary object to a non const reference
                            // hence the compiler error.
        m_size(nbytes)
    {}
    

    我会这样做:

    #include <iostream>
    
    struct mock_membuf : public std::streambuf
    {
        mock_membuf(char* begin, char* end) {
            this->setg(begin, begin, end);
        }
    };
    
    struct mock_stream: public std::istream
    {
        mock_membuf     streamBuffer;
        public:
            mock_stream(char* buffer, int offset, int nbytes)
                : std::istream(nullptr)
                , streamBuffer(buffer + offset, buffer + offset + nbytes)
            {
                rdbuf(&streamBuffer);
            }
    };
    
    int main()
    {
        char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";
    
        std::string line;
        mock_stream in(buffer, 5, 10);
        while (std::getline(in, line)) {
            std::cout << "line: " << line << "\n";
        }
        return 0;
    }