I'm trying to write a template operator for any iterable container. Getting a strange error:
#include <iostream>
template <typename C>
std::ostream& operator<<(std::ostream& os, const C& c) {
os << "[";
for (const auto& v : c) {
os << v << " ";
}
os << "]";
return os;
}
vec.cc:5:6: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::ostream' (aka 'basic_ostream') and 'const char [2]') os << "["; ~~ ^ ~~~
Why this error? And how do I achieve what I want?
Adding
template <typename C>
std::ostream& operator<<(std::ostream& os, const C& c) {
os << "[";
for (const auto& v : c) {
os << v << " ";
}
os << "]";
return os;
}
Conflicts with the other global overloads of operator <<
.
To fix this we can constrain your template to any vector instead of any type using
template <typename C>
std::ostream& operator<<(std::ostream& os, const std::vector<C>& c) {
os << "[";
for (const auto& v : c) {
os << v << " ";
}
os << "]";
return os;
}
At this line:
os << "[";
The compiler finds two valid functions: the STL's and yours.
You need to be a bit more specific in your template declaration in order to resolve the conflict:
template <typename C>
std::ostream& operator<<(std::ostream& os, const std::vector<C>& c) {
...
Expanding this to containers in general would require a bit of finagling with std::enable_if<>
that will probably just confuse you further. I recommend you just add an overload for each type of container you want to support.
Edit: Also, overriding ostream << T
, for types you don't own is generally a bad idea as it will eventually cause conflicts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With