将Qt与STL和Boost混合 - 是否有任何桥梁可以轻松实现?

时间:2009-05-11 14:05:37

标签: c++ qt boost stl

是否有任何桥梁可以使Qt与STL和Boost混合尽可能无缝且简单?

这是对Mixing Qt and Boost的跟进,其中没有给出具体答案如何实现这一点。

3 个答案:

答案 0 :(得分:37)

您需要什么桥梁?

您可以将所有Qt容器类与std算法一起使用。 大多数时候我更喜欢Qt容器类,因为我确信它们使用写时复制习惯用法(常量时间操作)。 Qt的foreach函数创建了一个容器的副本,所以它很好,你知道它是一个恒定的时间操作。

如果Qt信号插槽机制变慢,您可以切换到升压替代方案。 关于Qt信号/插槽的好处是两个线程之间的信号/插槽连接。

QtConcurrent适用于BOOST.Lambda


对于“共享”子父关系,我使用这个辅助函数。

template <class Object>
static boost::shared_ptr<Object> makeSharedObject()
{
    using namespace boost;
    using namespace boost::lambda;
    return boost::shared_ptr<Object>( 
        new Object(),
        bind( &Object::deleteLater, _1 ) );
}

Boost.serialize不支持Qt容器,您必须自己编写序列化函数。 我希望在Qt流媒体课程和Boost.archive之间建立一座桥梁。

这是我的QList序列化模板,你可以弄清楚其余的......

///\file document is based on "boost/serialization/list.hpp"

namespace boost { 
    namespace serialization {

        //---------------------------------------------------------------------------
        /// Saves a QList object to a collection 
        template<class Archive, class U >
        inline void save(Archive &ar, const QList< U > &t, const uint /* file_version */ )
        {
            boost::serialization::stl::save_collection< Archive, QList<U> >(ar, t);
        }

        //---------------------------------------------------------------------------
        /// Loads a QList object from a collection 
        template<class Archive, class U>
        inline void load(Archive &ar, QList<U > &t, const uint /* file_version */ )
        {
                boost::serialization::stl::load_collection< 
                    Archive, 
                    QList<U>, 
                    boost::serialization::stl::archive_input_seq<Archive, QList<U> >,
                    boost::serialization::stl::no_reserve_imp< QList<U> > >(ar, t);
        }

        //---------------------------------------------------------------------------
        /// split non-intrusive serialization function member into separate
        /// non intrusive save/load member functions
        template<class Archive, class U >
        inline void serialize(Archive &ar, QList<U> &t, const uint file_version )
        {
            boost::serialization::split_free( ar, t, file_version);
        }

    } // namespace serialization
} // namespace boost

BOOST_SERIALIZATION_COLLECTION_TRAITS(QList)

如果您希望Boost.Bind将QPointer作为普通指针(如shared_ptr)处理:

namespace boost {

    template<typename T> T * get_pointer(QPointer<T> const& qPointer)
    {
        return qPointer;
    }
}

使用需要QIODevice的{​​{1}}

std::stream

示例

namespace boost {
    namespace iostreams {

        class IoDeviceSource 
        {
        public:
            typedef char char_type;
            typedef source_tag category;

            explicit IoDeviceSource(QIODevice& source) 
                : m_source(source) 
            {
            }

            std::streamsize read(char* buffer, std::streamsize n)
            {
                return return m_source.read(buffer, n);
            }   
        private:
            QIODevice& m_source;
        };

        class IoDeviceSink {

        public:
            typedef char char_type;
            typedef sink_tag category;

            explicit IoDeviceSink(QIODevice& sink)
                : m_sink(sink)
            {
            }

            std::streamsize write(const char_type* buffer, std::streamsize n) 
            {
                return m_sink.write(buffer, n);
            }

        private:
            QIODevice &m_sink;
        };

        class IoDeviceDevice {

        public:
            typedef char char_type;
            typedef seekable_device_tag category;

            explicit IoDeviceDevice(QIODevice& device)
                :m_device(device) {
            }

            std::streamsize write(const char_type *buffer, std::streamsize n)
            {
                return m_device.write(buffer, n);
            }

            std::streamsize read(char* buffer, std::streamsize n)
            {
                return m_device.read(buffer, n);
            }

            stream_offset seek(stream_offset off, std::ios_base::seekdir way)
            {
                using namespace std;
                stream_offset next(0);

                if(way==ios_base::beg)
                {
                    next = m_device.pos();
                } 
                else if(way==ios_base::cur)
                {
                    next = m_device.pos() + offset;
                } 
                else if(way==ios_base::end)
                {
                    next = m_device.size() -1 + offset;
                }
                else
                {
                    throw ios_base::failure("bad seek direction");
                }

                if( !m_device.seek(next) )
                {
                    throw ios_base::failure("bad seek offset");
                }
                return m_device.pos();
            }

        private:    
            QIODevice &m_device;
        };
    }
}

答案 1 :(得分:3)

究竟是什么问题?
如果需要,可以忽略所有Qt集合类,并使用STL等价物 同样,您可以使用Boost的跨平台文件/网络库。

使用Qt自己的主要原因可能是提升不一定广泛可用,特别是在移动设备上。对于简单的任务,一些Boost的库使用起来比使用Qt稍微复杂一些。

答案 2 :(得分:2)

一般来说,如果你坚持使用QT Collection而不是我们的STL,你在使用QT时会更好。 Qt,STL或Boost中没有任何东西可以排除在彼此之间使用它们。

使用智能指针时必须小心谨慎QT具有可以处理对象破坏的父/子关系,在Qt控制下释放对象会使你崩溃。