全局函数识别失败

Global function recognition failing

当有一个简单的 qtest 比较用户定义结构的 2 个不同对象时:

Test a, b = {1};
QCOMPARE(a, b);

为什么有区别:

(1)

static char* toString(const Test &)
{
    using QTest::toString;
    return toString("Test");
}

(2)

namespace {

char* toString(const Test &)
{
    using QTest::toString;
    return toString("Test");
}

} // unnamed namespace

第一个在比较对象时调用了函数,第二个没有!

如前所述 in this conclusion,除了匿名命名空间允许您定义 translation-unit-local 类型外,应该没有区别。嗯,这里好像反了

默认 QTest::toString 实现是函数模板:

template <class T> char *QTest::toString(const T &value);

专门化此模板似乎是提供自定义实现的一种方式,但您正在使用另一种方式,即向 toString 重载集添加一个函数。我没有查看 Qt 源代码,但似乎使用 ADL 执行查找匹配名称以构造重载集。

现在当你有了这个

struct Test {};

char *toString(const Test&);

它们在同一个(全局)命名空间中。这是可行的,因为使用 ADL 查找与 Test 相关的名称会拉入全局命名空间,而这正是您的 toString 重载所在的位置。但这不同于

struct Test {};

namespace {
    char *toString(const Test&);
}

因为后者与

相同
struct Test {};

namespace someRandomUniqueIdentifier {
    char *toString(const Test&);
}

using namespace someRandomUniqueIdentifier;

因此,当为类型 Test 实例化函数模板时,ADL 无法找到 toString 名称,因为 Test 未在(未命名的)[=21= 中声明] 命名空间。如果在匿名命名空间内定义 Test,则应调用适当的 toString 函数。

您链接的线程是关于 static 函数与匿名命名空间的。您遇到的问题与此无关,是查找规则,尤其是ADL。