Глобальное распознавание функции не удалось
При наличии простого 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
Первый действительно вызывает функцию при сравнении объектов, второй нет!
Как упомянуто в этом заключении, не должно быть никакой разницы, кроме того, что анонимные пространства имен позволяют вам определять тип перевода-единицы-локальный. Ну, здесь, похоже, все наоборот.
1 ответ
По умолчанию 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.