Реализация по умолчанию 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
не объявлено в (неназванном) someRandomUniqueIdentifier
пространстве имен. Если вы определяете Test
внутри анонимного пространства имен, должна быть вызвана соответствующая функция toString
.
Связанный вами поток о static
функциях и анонимных пространствах имен. Проблема, с которой вы столкнулись, не связана с этим, это правила поиска, особенно ADL.