2016-02-07 6 views
1

Я создал следующий класс:не может реализовать оператор ==(), чтобы сравнить объект пользовательского класса к QString

class videodup 
{ 
public: 
    videodup(QString vid = "", int m_a = 0, int m_b = 0); 
    ~videodup() {} 
    QString video; 
    bool operator==(const QString &str) const { return video == str; } 
bool operator==(const videodup &dup) const {return video == dup.video;} 
    QList<matchPair> matches; 
}; 

videodup::videodup(QString vid = "", int m_a = 0, int m_b = 0) 
{ 
    video = vid; 
    matches.append(matchPair(m_a, m_b)); 
} 

Я думал, что это позволит мне использовать в QList::contains()QString, но он дает мне ошибка:

/usr/local/Cellar/qt5/5.5.1_2/lib/QtCore.framework/Headers/qlist.h:981: error: invalid operands to binary expression ('videodup' and 'const videodup') 
     if (i->t() == t) 
      ~~~~~~^~ 
/Users/phire/Documents/workspace/VideoTwin/matchpair.h:30: candidate function not viable: no known conversion from 'const videodup' to 'QString &' for 1st argument 
    bool operator==(QString &str) { return video == str; } 
     ^

нарушитель линия:

if (frame.videomatches.contains(vid)) 

ч прежде чем это код объясняя строку выше

struct frm 
{ 
    QString file; 
    int position; 
    cv::Mat descriptors; 
    QList<videodup> videomatches; 
}; 
QList<frm> frames; 

void MainWindow::findDupes(frm &frame) 
{ 
    QString file = frame.file; 
    UMat mat = frame.descriptors.getUMat(cv::ACCESS_RW); 
    UMat indices; 
    UMat dists; 
    if (!mat.isContinuous() || mat.empty()) 
     return; 
    QTime timestamp(0,0,0,0); 
    timestamp = timestamp.addMSecs(frame.position); 
    try 
    { 
     mat = mat.reshape(1,1); 
     index.knnSearch(mat,indices,dists,5); 
    } 
    catch (Exception e) 
    { 
     qWarning() << "index search failure" << e.err.c_str() << e.msg.c_str(); 
    } 
    catch (exception& e) 
    { 
     qWarning() << "index search failure" << e.what(); 
    } 
// qDebug() << "indices cols" << indices.cols << "dists cols" << dists.cols; 
    db.transaction(); 
    QSqlQuery matches(db); 
    QStringList tempmatches; 
    Mat indicesMat = indices.getMat(cv::ACCESS_READ); 
    Mat distsMat = dists.getMat(cv::ACCESS_READ); 

    for (int i = 0; i < indicesMat.cols; i++) 
    { 
     if (indicesMat.at<int>(0,i) == -1 || distsMat.at<int>(0,i) > 12800) 
      continue; 
     try 
     { 
      QTime matchtime(0,0,0,0); 
      int matchms = frames.at(indicesMat.at<int>(0,i)).position; 
      QString vid = frames.at(indicesMat.at<int>(0,i)).file; 
      matchtime = matchtime.addMSecs(matchms); 
      int temp = distsMat.at<int>(0,i); 
      tempmatches.append(QString::number(indicesMat.at<int>(0,i))); 
      if (frame.videomatches.contains(vid)) 
      { 
       matchPair pair(frame.position, indicesMat.at<int>(0,i)); 
       frame.videomatches[ frame.videomatches.indexOf(vid) ].matches.append(pair); 
      } 
      else 
      { 
       frame.videomatches.append(videodup(vid,frame.position, indicesMat.at<int>(0,i))); 
      } 
//   qDebug() << frame.file << "frame"<< timestamp.toString("hh:mm:ss") << "match at"<< vid << matchtime.toString("hh:mm:ss") << "distance" << temp; 
     } 
     catch (Exception e) 
     { 
      qWarning() << "failure in indices" << e.err.c_str() << e.msg.c_str() << e.func.c_str(); 
     } 
     catch (exception &e) 
     { 
      qWarning() << "failure in indices" << e.what(); 
     } 
    } 
    QString temp(tempmatches.join(",")); 
    matches.prepare("UPDATE frames SET matches = :matches WHERE file = :file AND position = :position"); 
    matches.bindValue(":matches",temp); 
    matches.bindValue(":file",frame.file); 
    matches.bindValue(":position",frame.position); 
    if (!matches.exec()) 
     qWarning() << "couldn't add matches to frame in database"; 
    db.commit(); 
} 

Как я могу сделать мой собственный класс сопоставим с QString?

+0

Neal - это тот же код, или он изменился с тех пор? Вы, к сожалению, удалили пасту, опять же я забыл (и это неясно, в первую очередь), что такое 'frame',' frame.videomatches' и 'vid'. Это важно. – iksemyonov

+0

пытался только вставить соответствующие биты http://pastebin.com/8WP8jT5P – Neal

+0

Хорошо, я вижу вашу проблему, думая, как обойти ее. С STL это было бы легко возможно, с Qt мне нужно немного подумать. – iksemyonov

ответ

1

Сообщение об ошибке жалуется на попытку сравнения видеозаписей и видеоконференций.

Вам просто нужно определить функцию bool operator==(const videodup &) const.

QString упоминается в сообщении об ошибке, потому что это единственный тип, который videodup::operator==() принимает, так что компилятор пытается выполнить преобразование в QString, но считает, что она не может.

+0

Майкл, я как-то вижу это наоборот. 'bool QList :: contains (const T & value) const;' означает, что 'QList' будет только принимать' videoodup' и пытается преобразовать 'QString' в это. Я ошибаюсь? – iksemyonov

+0

Кроме того, я был бы признателен, если бы вы рассмотрели мой анализ вызовов выше, если бы я понял это правильно. – iksemyonov

+0

Я просто перехожу к тому, что говорят сообщения об ошибках. Первый говорит, что 'qlist.h: 981' пытается сравнить объект' videoodup' и 'const videoodup'. Второй говорит, что 'matchpair.h: 30' пытается преобразовать объект' const videoodup' в 'QString &', поэтому он может вызывать 'bool operator == (QString & str)', но он не может выполнить преобразование. –

1

ОК, это то, что я думаю, это гонг здесь. Во-первых, и прежде всего,

bool QList::contains(const T & value) const; 

Эта функция хочет (а) объект типа T (тип он хранит) или (б) объект типа R, которые могут быть каким-то образом превращается в T. Как именно? С помощью оператора преобразования R::T() или c'tor или R, который принимает T: R:R(T&). Понимаете, у вас есть именно то, что доступно последнему. videodup::videodup(QString&, int=default, int=default).

А вот это актуальная проблема:

После того, как компилятор успешно преобразует QString в videodup средствами вышеупомянутого конструктора, он хочет вызвать videodup::operator==(const videodup&), в соответствии с требованиями функции QList::contains(const T&), и не может найти один , Следовательно, вам нужно раскомментировать и реализовать videodup::operator==(const videodup&), как говорит Майкл.

Edit:

Я также считаю, что, чтобы избежать этого неявного преобразования, мы можем использовать функцию STL std::find<Iterator, T> и рычаги videodup::operator==(const QString&). Чтобы сделать это, просто замените

if (frame.videomatches.contains(vid)) { 

с

const auto &matches = frame.videomatches; 
if (std::find(matches.cbegin(), matches.cend(), vid) != matches.cend()) { 

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

 Смежные вопросы

  • Нет связанных вопросов^_^