使用 Ogre3d 的自定义流/streambuf 存在不明确的过载错误

发布于 2024-10-02 15:03:52 字数 4178 浏览 1 评论 0原文

目前正在尝试使用Ogre 和STL 创建一个XML 系统。作为概念证明,我们试图让它将 XML 文件的内容输出到我们的日志文件中。遗憾的是,我们当前的代码无法编译,我们也不知道为什么。相关代码如下:

这是一个我们继承的流类,用于简化自定义streambuf的管理。它存在的主要原因是删除其析构函数中的自定义streambuf。

class ResourceInputStream : public std::istream
{
    private:
        internal::OgreDataStreamBuf* OgreBuffer;
        ResourceManager* Manager;

        /// @internal
        /// @brief Called by the constructors to actually construct this class
        /// @param InputBuffer A pointer to an internal::OgreDataStreamBuf. A buffer to read from the disk access subsystem (which happens to be part of Ogre). This Stream will assume ownership of this buffer and will handle deleting it.
        /// @param ResourceManager_ Currently unused, future functionality may tuse this.
        void Construct(std::streambuf *InputBuffer, ResourceManager* ResourceManager_);

    protected:

    public:
        /// @brief Descriptive Constructor
        /// @param InputBuffer A pointer to an internal::OgreDataStreamBuf. A buffer to read from the disk access subsystem (which happens to be part of Ogre). This Stream will assume ownership of this buffer and will handle deleting it.
        /// @param ResourceManager_ Currently unused, future functionality may tuse this.
        /// @warning Do not delete the InputBuffer you pass in, this class will assume owner ship and delete it on it's own
        ResourceInputStream(std::streambuf *InputBuffer, ResourceManager* ResourceManager_) :
            std::istream(InputBuffer)
            { this->Construct(InputBuffer, ResourceManager_); }

        /// @brief Tears down the Stream, and Delete the Buffer Passed in.
        virtual ~ResourceInputStream();

};

这是自定义 Streambuf 类的定义。它使用 ogreDatastreambuf 从 Ogre 资源库管理的压缩文件中读取:

 class OgreDataStreamBuf : public std::streambuf
        {
            protected:
                /// @brief a shard_ptr to the internal Ogre Datastream
                Ogre::DataStreamPtr OgreStream;

            public:

                /// @brief constructor
                /// @param Datum A pointer to the Ogre Datastream that this stream will use
                OgreDataStreamBuf(const Ogre::DataStreamPtr& Datum) : OgreStream(Datum)
                {
                    #ifdef PHYSDEBUG
                    World::GetWorldPointer()->Log("Entering/Exiting OgreDataStreamBuf Constructor");
                    #endif
                }

                /// @brief Should get the amount of characters left in the sequence
                /// @returns -1 if no estimate could be made, other wise this returns an estimate of the amount of bytes in the buffer
                std::streamsize showmanyc();

                /// @brief Gets a sequence of characters
                /// @param s a Pointer to where the characters should go
                /// @param n How many characters
                /// @return This returns the amount of characters retrieved
                std::streamsize xsgetn(char* s, std::streamsize n);

                /// @brief puts a sequence of characters in
                /// @param s a Pointer to the characters
                /// @param n How many characters
                /// @return This returns the amount of characters inserted
                /// @detail currently unimplimented
                std::streamsize xsputn(const char_type*, std::streamsize n);
        };
    }

这是尝试使用此流类的代码片段。 TheWorld->LogStream 是一个 std::stringstream。

ResourceInputStream* XMLptr = TheWorld->GetResourceManager()->GetResourceStream("test.xml");
std::stringstream XMLStringStream;
(*XMLptr) >> XMLStringStream;
String ShouldHaveXML(XMLStringStream.str());
TheWorld->LogStream << "ShouldHaveXML: " << ShouldHaveXML << endl << "End XML Logging" <<endl;
TheWorld->Log("Delete XML Stream");
delete XMLptr;

尝试编译会产生此错误:

error: ambiguous overload for 'operator>>' in '* XMLptr >> XMLStringStream'

我已经研究了此错误,并且我能找到的唯一关于此的信息...这是由于某些不应该声明为 const 的内容造成的。据我们所知,我们的代码并非如此。所以我不知道为什么会发生这种情况,或者如何解决它。任何见解将不胜感激。

Currently trying to create an XML system using Ogre and the STL. As a proof of concept, we are trying to get it to output the contents of the XML file to our log file. Sadly our current code won't compile, and we don't know why. Relevant code follows:

Here is a stream class that we have inherited from to simplify management of a custom streambuf. The main reason it exists it to delete the custom streambuf in it's destructor.

class ResourceInputStream : public std::istream
{
    private:
        internal::OgreDataStreamBuf* OgreBuffer;
        ResourceManager* Manager;

        /// @internal
        /// @brief Called by the constructors to actually construct this class
        /// @param InputBuffer A pointer to an internal::OgreDataStreamBuf. A buffer to read from the disk access subsystem (which happens to be part of Ogre). This Stream will assume ownership of this buffer and will handle deleting it.
        /// @param ResourceManager_ Currently unused, future functionality may tuse this.
        void Construct(std::streambuf *InputBuffer, ResourceManager* ResourceManager_);

    protected:

    public:
        /// @brief Descriptive Constructor
        /// @param InputBuffer A pointer to an internal::OgreDataStreamBuf. A buffer to read from the disk access subsystem (which happens to be part of Ogre). This Stream will assume ownership of this buffer and will handle deleting it.
        /// @param ResourceManager_ Currently unused, future functionality may tuse this.
        /// @warning Do not delete the InputBuffer you pass in, this class will assume owner ship and delete it on it's own
        ResourceInputStream(std::streambuf *InputBuffer, ResourceManager* ResourceManager_) :
            std::istream(InputBuffer)
            { this->Construct(InputBuffer, ResourceManager_); }

        /// @brief Tears down the Stream, and Delete the Buffer Passed in.
        virtual ~ResourceInputStream();

};

Here is the definition for the custom streambuf class. It uses an ogreDatastreambuf to read from zipped files in that are managed by the Ogre resource library:

 class OgreDataStreamBuf : public std::streambuf
        {
            protected:
                /// @brief a shard_ptr to the internal Ogre Datastream
                Ogre::DataStreamPtr OgreStream;

            public:

                /// @brief constructor
                /// @param Datum A pointer to the Ogre Datastream that this stream will use
                OgreDataStreamBuf(const Ogre::DataStreamPtr& Datum) : OgreStream(Datum)
                {
                    #ifdef PHYSDEBUG
                    World::GetWorldPointer()->Log("Entering/Exiting OgreDataStreamBuf Constructor");
                    #endif
                }

                /// @brief Should get the amount of characters left in the sequence
                /// @returns -1 if no estimate could be made, other wise this returns an estimate of the amount of bytes in the buffer
                std::streamsize showmanyc();

                /// @brief Gets a sequence of characters
                /// @param s a Pointer to where the characters should go
                /// @param n How many characters
                /// @return This returns the amount of characters retrieved
                std::streamsize xsgetn(char* s, std::streamsize n);

                /// @brief puts a sequence of characters in
                /// @param s a Pointer to the characters
                /// @param n How many characters
                /// @return This returns the amount of characters inserted
                /// @detail currently unimplimented
                std::streamsize xsputn(const char_type*, std::streamsize n);
        };
    }

Here is The piece of code attempting to use this stream class. TheWorld->LogStream is a std::stringstream.

ResourceInputStream* XMLptr = TheWorld->GetResourceManager()->GetResourceStream("test.xml");
std::stringstream XMLStringStream;
(*XMLptr) >> XMLStringStream;
String ShouldHaveXML(XMLStringStream.str());
TheWorld->LogStream << "ShouldHaveXML: " << ShouldHaveXML << endl << "End XML Logging" <<endl;
TheWorld->Log("Delete XML Stream");
delete XMLptr;

Attempting to compile produces this error:

error: ambiguous overload for 'operator>>' in '* XMLptr >> XMLStringStream'

I've researched this error, and the only thing I can find about this... it's due to something being declared const that shouldn't. That isn't the case with our code as far as we can tell. So I'm at a loss as to why this is happening, or how to go about fixing it. Any insights would be greatly appreciated.

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

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

发布评论

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

评论(1

無處可尋 2024-10-09 15:03:52

看起来这里有很多额外的不需要的信息,问题的关键是没有从 istream 中获取流操作符>>到 ostream。

所有 Ogre 和自定义类的东西都不是必需的,同时我们设法使用简单的解决方法从类中获取数据:

ResourceInputStream* XMLptr = TheWorld->GetResourceManager()->GetResourceStream("test.xml");
char chararray[401];
chararray[400]='\0';
XMLptr->read(chararray, 400);
String ShouldHaveXML( chararray );

这只是测试代码,我总是建议在假设您阅读之前使用 istream::gcount您请求的数据量。

It would appear that there is a lot of extra unneeded information here, The crux of the issue is that there is no streaming operator to got from an istream >> to an ostream.

All the Ogre and custom class stuff was simply not required, in the mean time we managed to get our data out of the class using s simple workaround:

ResourceInputStream* XMLptr = TheWorld->GetResourceManager()->GetResourceStream("test.xml");
char chararray[401];
chararray[400]='\0';
XMLptr->read(chararray, 400);
String ShouldHaveXML( chararray );

This is just test code, I would always suggest using istream::gcount before assuming you read the amount of data you requested.

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