I made overload for ostream operator<< for std::vector in namespace printable.
As far as I understand, ADL will not see this overload implicitly, because std::vector is not a member of printable, so we must use printable namespace in calling code to see this overload.
In other namespace, my::fails i define another overload for my class foo. After that code breaks and doesn't compile.
In namespace my::suddenly_works I'm not using whole namespace printable, only operator<<, and... everything is ok. Why? What's the difference.
After that, in my::works I don't define any additoinal overloads and simply use namespace printable, using overloaded operator. Everything is fine, as expected.
So, the question is: how to correctly overload ostream operator<< in namespace for types not defined in this namespace, and how to use these overloads in another namespaces on calling side.
Also, as a side question, what's the difference between using namespace printable and using printable::operator<< in given example?
Here is the code (godbolt link):
#include <iostream>
#include <vector>
namespace printable
{
template <typename T>
inline auto operator<<(std::ostream& os, std::vector<T> const & v) -> std::ostream &
{
os << '[';
for (auto it = v.cbegin(); it != v.cend() - 1; ++it)
{
os << *it << ", ";
}
os << v.back() << ']';
return os;
}
}
namespace my::fails
{
struct foo {};
inline auto operator<<(std::ostream& os, foo const & f) -> std::ostream &
{
std::vector v{1, 2, 3, 4, 5};
std::cout << v << '\n';
return os;
}
using namespace printable;
void print_vec()
{
std::vector v{1, 2, 3, 4, 5};
std::cout << v << '\n';
}
}
namespace my::suddenly_works
{
using printable::operator<<;
struct foo {};
inline auto operator<<(std::ostream& os, foo const & f) -> std::ostream &
{
std::vector v{1, 2, 3, 4, 5};
std::cout << v << '\n';
return os;
}
void print_vec()
{
std::vector v{1, 2, 3, 4, 5};
std::cout << v << '\n';
}
}
namespace my::works
{
using namespace printable;
void print_vec()
{
std::vector v{1, 2, 3, 4, 5};
std::cout << v << '\n';
}
}
int main()
{
using namespace printable;
std::vector v{1, 2, 3, 4, 5};
std::cout << v << '\n';
my::works::print_vec();
my::suddenly_works::print_vec();
my::fails::print_vec();
}
I tried to understand how ADL and overload resolution works, bu can't wrap my had around it yet. Also, googling gave me nothing.