Qt: как вычесть два QSet из QString в случае режима нечувствительности

Я работаю над логической проблемой, используя Qt. У меня есть два набора QSet из QString:

QSet<QString> set1: [ "aaa", "BBB" ]
QSet<QString> set2: [ "aaa", "bbb", "ccc", "ddd" ]

Я хочу вычесть set1 из set2, поэтому я использую:

set2.subtract( set1 );

И я получаю:

set2: ["bbb", "ccc", "ddd"]

Но в этом случае "bbb" не удаляется из set2, хотя set1 содержит эту запись. Это связано с тем, что метод QString::contains по умолчанию (это метод, используемый QSet::subtract) чувствителен к регистру.

Существует еще один метод QString::contains, который принимает параметр для определения режима чувствительности к регистру, но я действительно не понимаю, как его использовать.

Кто-нибудь знает, как сделать вычитание без учета регистра между двумя QSet из QString, пожалуйста?

Вот что я пробовал до сих пор:

Преобразовать оба набора в верхний регистр. Набор2 отображается в списке, поэтому не будет лишним, если все элементы будут в верхнем регистре (или ни в одном из них).

Расширить класс QSet и переопределить метод вычитания Я пытался расширить этот класс с помощью пользовательского класса MyStringSet, но мне не очень удобно работать с Qt, и это кажется мне довольно сложным.


person Gildas    schedule 04.05.2011    source источник


Ответы (2)


Классы контейнеров Qt в значительной степени совместимы с STL. А std::set_difference позволяет указать компаратор. Это очень полезно, когда вам нужна нечувствительность к регистру только в некоторых случаях или вы не хотите возиться с получением стандартных типов:

struct qstring_compare_i
{
    bool operator()(const QString & x, const QString y) const
    { return QString::compare(x, y, Qt::CaseInsensitive) < 0; }
};

static QSet<QString> substract_sets(const QSet<QString> & qs1, const QSet<QString> & qs2)
{
    std::set<QString> r;
    std::set_difference(qs1.begin(), qs1.end(), qs2.begin(), qs2.end(), std::inserter(r, r.end()), qstring_compare_i());

    QSet<QString> result;
    for(std::set<QString>::iterator i=r.begin();i!=r.end();++i) {
        result << *i;
    }
    return result;
}
person Stephen Chu    schedule 04.05.2011

Самым быстрым способом было бы создать подкласс QString таким образом и переопределить компараторы, в приведенном ниже примере я сделал оператор равенства:

  class QStringInsensitive: public QString
  {
     bool operator==(const QString& other) const
     {
        return (0 == this->compare(other, Qt::CaseInsensitive));
     }
  };
  QSet< QStringInsensitive > set;
person JadziaMD    schedule 04.05.2011
comment
Спасибо, как я уже сказал, мне не совсем удобно с Qt. С вашим решением я не могу вставить QString в свой QSet‹QStringInsensitive›. Поэтому я думаю, что мне нужно сохранить свой QSet‹QString›, но я должен преобразовать свой QString в QStringInsensitive. - person Gildas; 04.05.2011
comment
Как вы думаете? Потому что я не знаю, должен ли я создавать конструктор QStringInsensitive(const QString&) или кастинг. - person Gildas; 04.05.2011
comment
Привет, я безуспешно пробовал это решение: QString *entry; QStringInsensitive *entryInsensitive = qobject_cast‹QStringInsensitive *›(entry); У меня есть эта ошибка: нет соответствующей функции для вызова 'qobject_cast(QString*&)'. Я не могу найти ни одного примера в Интернете или в документе, чтобы сделать это приведение. Здесь может понадобиться помощь, пожалуйста :) - person Gildas; 05.05.2011
comment
Хорошо, ошибка вполне очевидна: QString не наследует QObject. Я действительно запутался сейчас. Разве QObject не является родительским классом для всех классов Qt? - person Gildas; 05.05.2011
comment
Краткий ответ - нет. Более длинный ответ заключается в том, что только классы, которые должны обрабатывать сигналы и слоты, будут объектом Qt. doc.qt.nokia.com/latest/qobject.html - person JadziaMD; 05.05.2011
comment
Итак, что я могу использовать для преобразования QString в QStringInsensitive, пожалуйста? - person Gildas; 05.05.2011
comment
Используйте этот конструктор преобразования: QStringInsensitive(QString q): QString(q) { } - person JadziaMD; 06.05.2011