I am trying to serialize an object of std::unordered_map<QString, QString> and place in QSettings, which I hope to read back later on. Reading the docs, I need to do 2 things: declare it as a meta type and register stream operators, which I did. Here is a complete example reproducing the error:
#include <QCoreApplication>
#include <QDataStream>
#include <QDebug>
#include <QSettings>
#include <QString>
#include <unordered_map>
namespace std {
template <>
struct hash<QString> {
  std::size_t operator()(const QString &s) const noexcept {
    return static_cast<std::size_t>(qHash(s));
  }
};
}  // namespace std
using StrMap = std::unordered_map<QString, QString>;
inline QDataStream &operator<<(QDataStream &out, const StrMap &map) {
  for (auto &&elm : map) {
    out << elm.first << elm.second;
  }
  return out;
}
inline QDataStream &operator>>(QDataStream &in, StrMap &map) {
  QString key;
  QString val;
  while (not in.atEnd()) {
    in >> key >> val;
    map.insert_or_assign(std::move(key), std::move(val));
  }
  return in;
}
Q_DECLARE_METATYPE(StrMap)
int main(int argc, char *argv[]) {
  QCoreApplication a(argc, argv);
  qRegisterMetaTypeStreamOperators<StrMap>("StrMap");
  {
    StrMap map{
        {"1", "1"},
        {"2", "2"},
        {"3", "3"},
        {"4", "4"},
    };
    QSettings settings{"TestOrg", "TestApp"};
    QVariant var;
    var.setValue(map);
    settings.setValue("StrMap", std::move(var));
  }
  QSettings settings{"TestOrg", "TestApp"};
  StrMap map{settings.value("StrMap").value<StrMap>()};
  for (auto &&pair : map) {
    qDebug() << pair.first << " - " << pair.second << '\n';
  }
  return a.exec();
}
Here when I read back the map object which I serialized, I get an additional element with empty key and empty value. Output:
""  -  ""
"1"  -  "1"
"2"  -  "2"
"4"  -  "4"
"3"  -  "3"
What am I doing wrong? I never placed that empty element. 
Some people are going to point me to "Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?" post, but the main differences here are, I know exactly how many elements I have placed there, so I won't read after the end, and there is apparently no way to convert QDataStream objects into bool implicitly, so I can't do while (in >> key >> val){...}.
 
    