Operator overloading with function template

Viewed 114

My job is to overload operator<< so it can print any object (e.g std::vector, std::set, std::map, std::deque, etc.)

With my basic knowledge of templates and searching the web I came out with something like this:

template <typename T>
std::ostream& operator<<(std::ostream& stream, const std::vector<T>& v){
    stream << '[';
    for(const auto& element : v){
        stream << element << ' ';
    }
    stream << ']';
    
    return stream;
}

int main(){
    std::vector<double> foo = {1.2, 2.1, 3.56};
    std::set<double> roo = {1.2, 2.1, 3.56};
    
    std::cout << foo << std::endl;
    std::cout << roo << std::endl;
}

But it won't print std::set or any other object. I've tried replacing const std::vector<T>& v with const T& v but it won't compile. Any tips on how can I approach this issue?

1 Answers

I've tried replacing const std::vector<T>& v with const T& v but it won't compile.

You can put constraints on the type to avoid conflict with overloaded operator<< provided by the library. E.g.

// works on types supporting std::begin and std::end
template <typename T>
auto operator<<(std::ostream& stream, const T& v) -> decltype(std::begin(v), std::end(v), stream) {
    stream << '[';
    for(const auto& element : v){
        stream << element << ' ';
    }
    stream << ']';
    
    return stream;
}

LIVE

Related