Congrats! You've been bitten by subtle Argument-Dependent-Lookup (aka
Koenig Lookup) rules.
In your old namespace (file_util), there were no namespace-dependent
overloads of operator<<, so it searched the global namespace (::),
which is where the char16* (FilePath::StringType on Windows) exists.
This is because it's non-spec-conformant code to introduce the
overload in the std:: namespace, and since char16* (aka wchar_t) is
treated a primitive type, there's no type-dependent namespace to look
it up.
In your new namespace (base), there is - and thus name lookup does not
search the global namespace, because it finds *possible* overloads in
base::.
Adding a "using ::operator<<" in the function(s) where you attempt to
perform the streaming operation will pull in the ::operator<<
overloads (but, surprise, it'll break other namespace-dependent
lookups!), but it's a solution.
Does the above all sound like Greek? Welcome to the club! I'm sure
I've probably half-botched the explanation above, but that's at least
the reason.
Of course, the easier solution is force it into a char* type - such as
AsUTF8Unsafe(). Depends on if it is testing only or (potentially)
production.