为什么 QCOMPARE(QString("1"), "1") 会导致链接器错误?

Why does QCOMPARE(QString("1"), "1") cause a linker error?

我正在探索 Qt 的单元测试框架,我注意到一件奇怪的事情——考虑到 QString 已经为 const char * 实现了相等运算符,我本以为 QCOMPARE(QString("1"), "1") 可以正常工作,但是相反,它会导致链接器错误:

tst_untitled14test.obj:-1: error: LNK2019: unresolved external symbol "bool __cdecl QTest::qCompare<class QString,char const [2]>(class QString const &,char const (&)[2],char const *,char const *,char const *,int)" (??$qCompare@VQString@@$$BY01$$CBD@QTest@@YA_NABVQString@@AAY01$$CBDPBD22H@Z) referenced in function "private: void __thiscall Untitled14Test::testCase1(void)" (?testCase1@Untitled14Test@@AAEXXZ)

示例代码:

QVERIFY(QString("1") == "1");         // This works.
QCOMPARE(QString("1"), QString("1")); // This works.
// QCOMPARE(QString("1"), "1");       // Causes a linker error!

这是为什么? QCOMPARE 不使用两个项的相等运算符吗?

编辑:由于在评论中被问到,项目是通过Qt Creator的单元测试向导创建的(文件->新建项目->其他项目->Qt单元测试), 所以当然已经设置好了, QT += testlib 也包含在内了.

来自 Qt documentation

QCOMPARE is very strict on the data types. Both actual and expected have to be of the same type, otherwise the test won't compile. This prohibits unspecified behavior from being introduced; that is behavior that usually occurs when the compiler implicitly casts the argument.

在源代码中 QCOMPARE 看起来像

#define QCOMPARE(actual, expected) \
do {\
    if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
        return;\
} while (0)

template <typename T>
inline bool qCompare(T const &t1, T const &t2, const char *actual, const char *expected,
                        const char *file, int line)
{
    return compare_helper(t1 == t2, "Compared values are not the same",
                              toString(t1), toString(t2), actual, expected, file, line);
}

这是一个模板,要求第一个和第二个参数是同一类型。