I am trying to understand why the following code does not compile:
namespace ns {
struct S {};
}
namespace alleq {
inline bool
operator==(const ns::S &, const ns::S &)
{
return true;
}
}
namespace ns {
using namespace alleq;
// using alleq::operator==; // Works if you uncomment this
}
ns::S a;
void
f()
{
::ns::operator==(a, a); // OK
a == a; // Error: no match for 'operator=='
}
The first line of function f
does compile, which makes me believe that namespace ns
contains a function operator==
. However, when I compare two values of type ns::S
, this operator==
function is not found. By contrast, a using declaration does work as expected, and allow the second line of f
to find ns::operator==
by ADL.
I suspect the reason has to do with the fact that a using directive is supposed to make the symbol appear as if it is in the global namespace ::
(because that is the common ancestor of namespaces alleq
and ns
). But if that were really the case, then why would ::ns::operator==
find the function?
More generally, I'm trying to provide some useful operator==
(and related) overloads in a library, but not force people to use the definitions if they don't want them. I was hoping to allow people to enable or not enable operator== (and related other operators) on their types based on whether they import a dedicated operator namespace into their own namespace. Now it looks like people may have to write a host of using declarations (which I could simplify with a macro, but yuck).