I have created this template function:
// Output stream for container of type C
template<class C>
ostream& operator<<(ostream& os, const C& c) {
os << "[";
for (auto& i : c) {
os << i;
if (&i != &c.back()) os << ", ";
}
os << "]" << endl;
return os;
}
but I have this error:
error: use of overloaded operator '<<' is ambiguous (with operand types 'std::ostream' (aka 'basic_ostream') and 'const char [2]')
The error is in the first line of the body of the function.
This declaration
template<class C>
ostream& operator<<(ostream& os, const C& c)
is a match for any type. In particular, when you call inside that operator
os << "[";
os << i;
os << "]" << endl;
For all this calls your operator is a match in addition to the already existing output operators for strings and endl
.
Don't provide operators for types you don't own. Instead you can write a
void print(const my_container&);
or use a tag to resolve ambiguity. For example you could use a
template <typename T>
struct pretty_printed_container {
const T& container;
};
template <typename T>
pretty_printed_container<T> pretty_print(const T& t) { return {t};}
modify your output operator accordingly
template<class T>
std::ostream& operator<<(std::ostream& os, const pretty_printed_container<T>& c) {
os << "[";
for (const auto& i : c.container) {
os << i;
if (&i != &c.container.back()) os << ", ";
}
os << "]" << std::endl;
return os;
}
And then use it like this
int main() {
std::vector<int> x{1,2,3,4,5};
std::cout << pretty_print(x);
}
Output:
[1, 2, 3, 4, 5]