When having a simple qtest which compares 2 different objects for a user-defined struct:
Test a, b = {1};
QCOMPARE(a, b);
Why is there a difference between:
(1)
static char* toString(const Test &)
{
using QTest::toString;
return toString("Test");
}
And
(2)
namespace {
char* toString(const Test &)
{
using QTest::toString;
return toString("Test");
}
} // unnamed namespace
The first one does call the function when comparing the objects, the second one does not!
As mentioned in this conclusion, there should be no difference except anonymous namespaces allow you to define translation-unit-local type. Well, here it looks like it's the opposite.
The default QTest::toString
implementation is a function template:
template <class T> char *QTest::toString(const T &value);
Specializing this template seems to be one way to provide a custom implementation, but you are using the other one, i.e., adding a function to the toString
overload set. I haven't looked at the Qt sources, but it seems that the lookup for matching names to construct an overload set is performed using ADL.
Now when you have this
struct Test {};
char *toString(const Test&);
they are in the same (global) namespace. This works, because using ADL to look for names related to Test
pulls in the global namespace, and that's where your toString
overload resides. But that differs from
struct Test {};
namespace {
char *toString(const Test&);
}
because the latter is identical to
struct Test {};
namespace someRandomUniqueIdentifier {
char *toString(const Test&);
}
using namespace someRandomUniqueIdentifier;
and hence when instantiating a function template for the type Test
, ADL fails to find the toString
name as Test
is not declared in the (unnamed) someRandomUniqueIdentifier
namespace. If you define Test
inside the anonymous namespace, the appropriate toString
function should be invoked.
The thread you linked is about static
functions vs. anonymous namespaces. The issue you encounter isn't related to that, it's the lookup rules, particularly ADL.