全局函数识别失败
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。
当有一个简单的 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。