无法实现 operator==() 来将自定义 class 对象与 QString 进行比较
Cannot implement operator==() to compare a custom class object to a QString
我创建了以下 class:
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();
}
如何使我的自定义 class 与 QString
相媲美?
好的,这就是我认为的重点。首先,也是最重要的,
bool QList::contains(const T & value) const;
此函数需要 (a) T
类型的对象(它存储的类型)或 (b) 可以以某种方式转换为 T
类型的 R
对象.究竟如何?通过转换运算符 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&)
,正如 Michael 所说。
编辑:
我也认为要避免这种隐式转换,我们可以使用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()) {
我很确定这将直接使用现有的运算符,避免不必要的转换。
错误消息抱怨试图比较 'videodup' 和 'const videodup'。
你只需要定义一个bool operator==(const videodup &) const
函数。
QString
在错误中被提及,因为这是 videodup::operator==()
接受的唯一类型,因此编译器尝试转换为 QString
但发现它不能。
我创建了以下 class:
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();
}
如何使我的自定义 class 与 QString
相媲美?
好的,这就是我认为的重点。首先,也是最重要的,
bool QList::contains(const T & value) const;
此函数需要 (a) T
类型的对象(它存储的类型)或 (b) 可以以某种方式转换为 T
类型的 R
对象.究竟如何?通过转换运算符 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&)
,正如 Michael 所说。
编辑:
我也认为要避免这种隐式转换,我们可以使用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()) {
我很确定这将直接使用现有的运算符,避免不必要的转换。
错误消息抱怨试图比较 'videodup' 和 'const videodup'。
你只需要定义一个bool operator==(const videodup &) const
函数。
QString
在错误中被提及,因为这是 videodup::operator==()
接受的唯一类型,因此编译器尝试转换为 QString
但发现它不能。