2016-02-07 24 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)) 

ħ ERE是解釋上述

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

尼爾是相同的代碼,或自從它改變?你很遺憾地刪除了這個貼,我忘記了(首先它並不清楚)'frame','frame.videomatches'和'vid'是什麼。這很重要。 – iksemyonov

+0

試圖只粘貼相關位http://pastebin.com/8WP8jT5P – Neal

+0

好吧,我看到你的問題,想着如何規避它。使用STL很容易,Qt我需要考慮一下。 – iksemyonov

回答

1

錯誤消息抱怨試圖比較'videodup'和'const videodup'。

您只需要定義一個bool operator==(const videodup &) const函數。

QString中提到的錯誤,因爲這是唯一的類型videodup::operator==()接受,所以編譯器試圖做一個轉換QString但發現它不能。

+0

邁克爾,我不知何故以相反的方式看到它。 'bool QList :: contains(const T&value)const;'意味着'QList'只接受'videodup'並試圖將'QString'轉換爲''。我錯了嗎? – iksemyonov

+0

另外,如果我看到了上面的電話分析,如果得到了正確的結果,我將不勝感激。 – iksemyonov

+0

我只是想通過錯誤消息說什麼。第一個說'qlist.h:981'試圖比較'videodup'和'const videodup'對象。第二個說'matchpair.h:30'試圖將'const videodup'對象轉換爲'QString&',因此它可以調用'bool operator ==(QString&str)',但它不能執行轉換。 –

1

好的,這是我認爲是在這裏鑼。第一,也是最重要的,

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

該功能希望的(a)T類型(類型它存儲)或(b)R類型,可以以某種方式轉換爲T的一個對象的對象。究竟如何?藉助於轉換運算符R::T()或c'tor或R,其需要TR:R(T&)。看,你有完全可用的後者。 videodup::videodup(QString&, int=default, int=default)

這裏,它的實際問題:

一旦成功編譯轉換成QString通過videodup上述構造的手段,它需要調用videodup::operator==(const videodup&),所要求的QList::contains(const T&)功能,並不能找到一個。因此,您需要取消註釋並實施videodup::operator==(const videodup&),就像邁克爾說的那樣。

編輯:

我也認爲要避免這種隱式轉換,我們可以使用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()) { 

我敢肯定,這會直接使用現有的運營商,避免了不必要的轉換。

相關問題