1
votes

I'm trying to print a set of pairs using std::cout, but it's not compiling. I'm using C++14 on XCode 9. The error occurs on cout<<(*it); line

Error: Invalid operands to binary expression ('ostream' (aka 'basic_ostream') and 'const value_type' (aka 'const std::__1::pair'))

Candidate function not viable: no known conversion from 'const value_type' (aka 'const std::__1::pair') to 'const void *' for 1st argument; take the address of the argument with &

#include <iostream>
#include <set>
#include <map>
using namespace std;

template <class P, class Q> ostream& operator<<(ostream &out, pair<P,Q>& p)
{
    cout<<"["<<p.first<<","<<p.second<<"]";
    return out;
}

template <class T> ostream& operator<<(ostream &out, set<T> &S)
{
    cout<<"{";
    for(typename set<T>::iterator it = S.begin(); it != S.end(); it++) {
        cout<<(*it);   //Error occurs here
        if(next(it,1) != S.end()) cout<<",";
    }
    cout<<"}";
    return out;
}

int main() {
    set<pair<int,int>> s;
    s.insert({1,2});
    cout<<s;
    return 0;
}
1
Your overload should take std::pair by const reference. (same for std::set)Jarod42
Also, use ++it instead of it++ in the loop.Daniel Langr
Thank you! And could you tell me the difference ++it and it++ makes? For integers I've always been using postfix increments.Prayansh Srivastava
@PrayanshSrivastava See, e.g., here: stackoverflow.com/q/1077026/580083Daniel Langr
@DanielLangr: or use for range: cout << "{"; auto sep = ""; for (const auto& e : S) { cout << sep << e; sep = ","; } cout "}";Jarod42

1 Answers

0
votes

Iterator of std::set is a constant bidirectional iterator (at least starting from C++11). Its dereferencing therefore result in a constant reference to set element/key (you may not modify set keys directly, which makes sense, since it would break the underlying data structure - usually some form of search tree). This reference represents a constant lvalue argument, which may not be bound to parameter of non-const reference type (p in operator<<). As others already suggested, use const references as parameters instead.