Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Using QDataStream with STL containers



  • Hi,
    I'm trying to use QDataStream for serialization with code that is mostly STL based but compiler never seems to find matching method.
    I tried to do the following:

    template<typename First, typename Second>
    inline QDataStream& operator<< (QDataStream& out, const std::pair<First,Second>& args)
    {
        out << args.first;
        out << args.second;
        return out;
    }
    template<typename First, typename Second>
    inline QDataStream& operator>> (QDataStream& in, std::pair<First,Second>& args)
    {
        in >> args.first;
        in >> args.second;
        return in;
    }
    template<typename Container,typename Val>
    inline QDataStream& operator<< (QDataStream& out, const Container& args)
    {
        out << (int)args.size();
        for (const Val& val : args )
        {
            out << val;
        }
        return out;
    }
    template<typename Container,typename Val>
    inline QDataStream& operator>> (QDataStream& in, Container& args)
    {
        int length=0;
        in >> length;
        for (int i = 0 ; i < length ; ++i)
        {
            Val obj;
            in >> obj;
            args.insert(args.end(),obj);
        }
        return in;
    }
    inline QDataStream& operator<< (QDataStream& out, const std::string& args)
    {
        QByteArray temp(args.c_str(),args.size());
        out << temp;
        return out;
    }
    inline QDataStream& operator>> (QDataStream& in, std::string& args)
    {
        QByteArray temp;
        in >> temp;
        args= std::string(temp.constData());
        return in;
    }
    

    But it fails . For example for "in >> StatesSet "
    I'm getting:

    no match for 'operator>>' (operand types are 'QDataStream' and 'StatesSet {aka std::set<long int>}')
         in >> Values;
    note: candidate: template<class Container, class Val> QDataStream& operator>>(QDataStream&, Container&)
     inline QDataStream& operator>> (QDataStream& in, Container& args)
                                ^~~~~~~~
      template argument deduction/substitution failed:
      couldn't deduce template parameter 'Val'
    

    Can someone tell me what am doing wrong or suggest a better way to serialize stl using Qt ? Thank you very much in advance .


  • Qt Champions 2019

    @Eukaryote said in Using QDataStream with STL containers:

    template<typename Container,typename Val>
    inline QDataStream& operator<< (QDataStream& out, const Container& args)
    {
    out << (int)args.size();
    for (const Val& val : args )
    {
    out << val;
    }
    return out;
    }

    The compiler can't detmerine what Val is/should be. And it's also not needed. Either use auto

    for (const auto &val : args)

    or use std::set value_type

    typename Container::value_type Val;
    for (const Val &val : args)



  • Thanks for your reply, but this my original implementation was using auto , it didn't help.
    And I don't think using auto is much different from using template .


  • Qt Champions 2019

    This is working perfectly fine for me...

    template<typename Container>
    inline QDataStream& operator<< (QDataStream& out, const Container& args)
    {
        out << (int)args.size();
        for (const auto& val : args )
        {
            out << val;
        }
        return out;
    }
    template<typename Container>
    inline QDataStream& operator>> (QDataStream& in, Container& args)
    {
        int length=0;
        in >> length;
        args.clear();
        args.reserve(length);
        for (int i = 0 ; i < length ; ++i)
        {
            typedef typename Container::value_type valType;
            valType obj;
            in >> obj;
            args.push_back(obj);
        }
        return in;
    }
    
    int main(int argc, char **argv)
    {
        QDataStream ds;
        std::vector<int> cont;
        ds << cont;
        ds >> cont;
    }
    


  • Adding typedef typename Container::value_type valType; to the loop helped with this issue . Thank you very much .