A direct solution to your problem is that vector is a template for two types, not one, so you want to write:
template <typename... T, template <typename... > class Iterable> inline std::ostream& operator<<(std::ostream& os, const Iterable<T...>& iter) { s << "[ "; bool first = true; // not false for (const auto& e : iter) { // rest as before } return s << " ]"; }
This works, but a little unsatisfactorily - since some things that are templates are not iterable, and some things that are not templates. In addition, in our solution, we actually do not need Iterable or T So, how about we write something that accepts any range - where we define Range as something that begin() and end() :
template <typename Range> auto operator<<(std::ostream& s, const Range& range) -> decltype(void(range.begin()), void(range.end()), s) {
If this is too general, then you can do:
template <typename T> struct is_range : std::false_type; template <typename T, typename A> struct is_range<std::vector<T,A>> : std::true_type;
Barry
source share