Обратите внимание, что даже с учетом скобок, предложенных Lightness, код, который вы показываете, является исключительно fr agile.
Я полагаю, что вы изначально находитесь на территории только ADL из-за поиска зависимых имен внутри макроса (см. последние примечания https://en.cppreference.com/w/cpp/language/adl), и ваш код явно не пригоден для ADL. Добавление скобок делает все это просто безусловным поиском, а не только ADL (опять же, предположение). Не-ADL часть неквалифицированного поиска спасет вас в этом случае, но она отделится от совершенно несвязанных изменений кода.
Рассмотрим этот код вместо TEST_CASE
, то есть то, что использование скобок предположительно сводится к :
namespace test
{
bool foo()
{
auto t1 = std::make_pair(A::B::C::S(), std::any());
auto t2 = std::make_pair(A::B::C::S(), std::any());
return t1 == t2;
}
}
Это компилируется и работает, как и ожидалось: https://godbolt.org/z/HiuWWy
Теперь добавьте совершенно не связанный operator==
между вашим глобальным operator==
и t1 == t2
:
namespace test
{
struct X{};
bool operator==(X, X);
bool foo()
{
auto t1 = std::make_pair(A::B::C::S(), std::any());
auto t2 = std::make_pair(A::B::C::S(), std::any());
return t1 == t2;
}
}
И вы рассчитываете на счет: https://godbolt.org/z/BUQC9Y
operator==
в глобальном пространстве имен не найден, потому что ( не являющаяся частью ADL) поиск безусловного имени останавливается в включающей области действия first , которая имеет any operator==
. Поскольку в этом нет ничего полезного, он возвращается к использованию встроенного оператора сравнения std::pair
(найденного через ADL), который не будет работать.
Просто поместите перегрузки операторов в пространства имен объектов, которые они работать на. И, как следствие, не перегружайте операторов для объектов из std
(или других пространств имен, к которым вы не имеете права прикасаться).
Добавление из комментариев:
Стандарт в настоящее время также говорит, что учитываются пространства имен аргументов шаблона, поэтому будет работать operator==
в namespace C
(поскольку отсюда первый аргумент шаблона std :: pair): https://godbolt.org/z/eV8Joj
Тем не менее, 1. это меня не устраивает sh не слишком хорошо с вашим псевдонимом типа, и 2. есть некоторое движение, чтобы сделать ADL менее диким, и я видел обсуждение, чтобы избавиться от "рассмотреть пространства имен параметров шаблона". ». См. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0934r0.pdf:
С какой стати мы будем изучать пространства имен аргументов шаблона? Ничто в нем не может быть частью интерфейса типа, если только аргументы шаблона не были также базовыми классами или чем-то еще. - Херб Саттер
Я не знаю, где эта статья стоит сегодня, но я бы не стал полагаться на этот вид ADL в новом коде.