Russian Qt Forum

Qt => Общие вопросы => Тема начата: merke от Июнь 20, 2011, 17:16



Название: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 17:16
Всем привет.

К примеру есть такая структура:

Код:
struct my_struct
{
    int a;
    int b;
};

И есть карта следующего вида:

Код:
QMap<QString, my_struct> mapMain;

Потом я хочу проделать следующее:

 
Код:
   QByteArray arr;
    QDataStream stream(&arr, QIODevice::WriteOnly);
    stream.setVersion(QDataStream::Qt_4_7);

    my_struct udt;

    udt.a = 1;
    udt.b = 2;

    mapMain.insert("Hello", udt);

    stream << mapMain;

Компилятор на это говорит очень сильным и громким матом:

Код:
C:\dev\est_strucrt-build-desktop\..\..\Qt\2010.05\qt\src\corelib\io\qdatastream.h:427: ошибка: no match for 'operator<<' in 'operator<<(((QDataStream&)((QDataStream*)out)), ((const QString&)((const QString*)it.QMap<Key, T>::const_iterator::key [with Key = QString, T = my_struct]()))) << it.QMap<Key, T>::const_iterator::value [with Key = QString, T = my_struct]()'

Далее делаю вот это:

 
Код:
  friend QDataStream &operator<<(QDataStream &out, const QMap<QString, my_struct> &map)
    {
        //Тут код :)
        return out;
    }

И всё равно ругается. Как же запихать карту в датастрим?

Помогите, пожалуйста!!!


Название: Re: QMap в QDataStream
Отправлено: kambala от Июнь 20, 2011, 17:25
не надо никаких френдов - лучше вне класса опиши эту функцию


Название: Re: QMap в QDataStream
Отправлено: BRE от Июнь 20, 2011, 17:25
Ты "научи" QDataStream структуру my_struct сохранять, а с остальным он сам разберется.   :)


Название: Re: QMap в QDataStream
Отправлено: kambala от Июнь 20, 2011, 17:26
мы ж не видим какой там код в "Тут код" - может поля структуры явно считываются ;)


Название: Re: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 17:31
"Тут код"=)

Код:
 friend QDataStream &operator<<(QDataStream &out, const QMap<QString, my_struct> &map)
    {

        QMapIterator<QString, my_struct> iter(map);
        while(iter.hasNext())
        {
            iter.next();
            out << iter.key();
            out << iter.value().a;
            out << iter.value().b;
        }
        return out;
    }

Объявил за классом один фиг также.

Научить просто структуру записывать уже научил) но хочется чтобы скинуть ему карту, а тот уже сам.


Название: Re: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 17:40
Интересно... если нажать на ошибку то переходит в файл QDataStream.h и там вот такой кол:

Код:
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map)
{
    out << quint32(map.size());
    typename QMap<Key, T>::ConstIterator it = map.end();
    typename QMap<Key, T>::ConstIterator begin = map.begin();
    while (it != begin) {
        --it;
        out << it.key() << it.value();
    }
    return out;
}

Значит это уже реализовано???


Название: Re: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 17:57
SOS SOS SOS!!! Please, help me! ;D


Название: Re: QMap в QDataStream
Отправлено: m_ax от Июнь 20, 2011, 18:06
Код
C++ (Qt)
QDataStream &operator<<(QDataStream &out, const my_struct &struct)
{
   out << struct.a;
   out << struct.b;
   return out;
}
 


Название: Re: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 18:11
Спасибо, но так уже делал... работает да)


Название: Re: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 18:15
Я просто делал вот так:

Код:
QByteArray arr;
QDataStream stream(&arr, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_4_7);

QMapIterator<QString, my_struct> iter(mapMain);
        while(iter.hasNext())
        {
            iter.next();

            stream << iter.key();
            stream << iter.value();
        }

Я посчитал, что это не красивая реализация, и подумал о том, почему бы сразу не скормить ему карту. оказывается так просто это не сделать, а жаль...


Название: Re: QMap в QDataStream
Отправлено: m_ax от Июнь 20, 2011, 18:36
Интересно... если нажать на ошибку то переходит в файл QDataStream.h и там вот такой кол:

Код:
template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map)
{
    out << quint32(map.size());
    typename QMap<Key, T>::ConstIterator it = map.end();
    typename QMap<Key, T>::ConstIterator begin = map.begin();
    while (it != begin) {
        --it;
        out << it.key() << it.value();
    }
    return out;
}

Значит это уже реализовано???

it.value() - это и есть my_struct. 
Очевидно, что для my_struct  должен быть реализован оператор <<
 


Название: Re: QMap в QDataStream
Отправлено: merke от Июнь 20, 2011, 18:42
О здорово, заработало)))

Да, оказывается если просто для структуры, переопределить оператор << то и карту можно уже передавать!!! как здорово!!! спасибо!!!!!!!!!!!!!!!!!


Название: Re: QMap в QDataStream
Отправлено: Igors от Июнь 20, 2011, 18:48
Очевидно, что для my_struct  должен быть реализован оператор <<
Ну это и для меня очевидно :) А вот пара моментов что нет, и было бы интересно узнать (углУбить свои знания)

- зачем QMap пишется задом наперед ?
- в чем "глубинный смысл" typename QMap<.. чем хуже (или почему нельзя) без typename ?

Спасибо


Название: Re: QMap в QDataStream
Отправлено: m_ax от Июнь 20, 2011, 19:04
Очевидно, что для my_struct  должен быть реализован оператор <<
Ну это и для меня очевидно :) А вот пара моментов что нет, и было бы интересно узнать (углУбить свои знания)

- зачем QMap пишется задом наперед ?
- в чем "глубинный смысл" typename QMap<.. чем хуже (или почему нельзя) без typename ?

Спасибо

1)Почему QMap задом наперёд.. Не знаю, есть ли в этом какой-нить сокральный смысл, нужно смотреть реализацию QDataStream. Возможно это и не спроста)

2) typename нужно писать, поскольку ConstIterator - есть некий вложенный идентификатор и без typename нельзя было бы создать объект it:
Код
C++ (Qt)
typename QMap<Key, T>::ConstIterator it = map.end();
 
Чтоб компилятор не гадал что это: статическая переменная класса или вложенный тип, как в примере выше.
Как то так)
 


Название: Re: QMap в QDataStream
Отправлено: ритт от Июнь 20, 2011, 19:56
О здорово, заработало)))

Да, оказывается если просто для структуры, переопределить оператор << то и карту можно уже передавать!!! как здорово!!! спасибо!!!!!!!!!!!!!!!!!

о, боже, боже...гениально!

...а потом открываем ассистант - и видим, что них оно не гениально, а вполне даже так и должно быть:
Цитировать
Reading and writing Qt collection classes

The Qt container classes can also be serialized to a QDataStream. These include QList, QLinkedList, QVector, QSet, QHash, and QMap. The stream operators are declared as non-members of the classes.

и
http://doc.trolltech.com/latest/qmap.html#operator-lt-lt-82
Цитировать
QDataStream & operator<< ( QDataStream & out, const QMap<Key, T> & map )

Writes the map map to stream out.

This function requires the key and value types to implement operator<<().

See also Format of the QDataStream operators.


Название: Re: QMap в QDataStream
Отправлено: Igors от Июнь 20, 2011, 21:51
2) typename нужно писать, поскольку ConstIterator - есть некий вложенный идентификатор и без typename нельзя было бы создать объект it:
Хм... а на MSVC 2008 проходит и без typename (недавно переносил код с Вындоуз на gcc и понадобилось добавить)

1)Почему QMap задом наперёд.. Не знаю, есть ли в этом какой-нить сокральный смысл, нужно смотреть реализацию QDataStream. Возможно это и не спроста)
QDataStream смотреть не нужно
Цитировать
If the map contains multiple items with key key, this function returns an iterator that points to the most recently inserted value. The other values are accessible by incrementing the iterator.


Название: Re: QMap в QDataStream
Отправлено: m_ax от Июнь 20, 2011, 22:49
Цитировать
Хм... а на MSVC 2008 проходит и без typename (недавно переносил код с Вындоуз на gcc и понадобилось добавить)
Ну дык MSVC же)

Цитировать
QDataStream смотреть не нужно

If the map contains multiple items with key key, this function returns an iterator that points to the most recently inserted value. The other values are accessible by incrementing the iterator.

А, ясненько)


Название: Re: QMap в QDataStream
Отправлено: lolbla2 от Февраль 06, 2012, 14:06
Цитировать
Хм... а на MSVC 2008 проходит и без typename (недавно переносил код с Вындоуз на gcc и понадобилось добавить)
Ну дык MSVC же)

Цитировать
QDataStream смотреть не нужно

If the map contains multiple items with key key, this function returns an iterator that points to the most recently inserted value. The other values are accessible by incrementing the iterator.

А, ясненько)

А у меня такая же проблема но с QVector вот ссылка http://www.prog.org.ru/index.php?topic=20863.msg142705#msg142705

Правда мне нужны оба оператора >> и <<