1
votes

I'm trying to find if my character hash table contains the first character of a string:

string minWindow(string s, string t) {
    unordered_map<char, int> charFinder;
    for (int i = 0; i < t.length(); ++i) {
        charFinder[t[i]] = 0;
    }
    cout << charFinder.find(s[0]) == charFinder.end() << endl;
    return "hi";
}

But I get this error for some reason. This doesn't make any sense to me. Anyone have any ideas?

Line 8: Char 14: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int> > >::iterator' (aka '_Node_iterator<std::pair<const char, int>, __constant_iterators::value, __hash_cached::value>'))
        cout << charFinder.find(s[1]) == charFinder.end() << endl;
        ~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/cstddef:124:5:
note: candidate function template not viable: no known conversion from 'std::ostream' (aka 'basic_ostream<char>') to 'std::byte' for 1st argument
    operator<<(byte __b, _IntegerType __shift) noexcept
    ^

I cutoff the rest of the long error message.

2

2 Answers

2
votes

Per Operator Precedence, operator<< has a higher precedence than operator==, so your cout expression:

cout << charFinder.find(s[0]) == charFinder.end() << endl;

Is being evaluated as if you had written it like this:

(cout << charFinder.find(s[0])) == (charFinder.end() << endl);

The compiler error is complaining about passing the std::unordered_map itself to operator<<, which is not what you intended. Look at the error message more carefully, that is exactly what it is pointing out. There is no operator<< for std::ostream that takes a std::unordered_map as input.

To fix this, you need to use parenthesis explicitly to tell the compiler what you really want, eg:

cout << (charFinder.find(s[0]) == charFinder.end()) << endl;

Otherwise, use a bool variable instead:

bool notFound = charFinder.find(s[0]) == charFinder.end();
cout << notFound << endl;

In C++20, you can use std::unordered_map::contains() instead:

cout << charFinder.contains(s[0]) << endl;

That being said, since you are not actually using the character counts at all, you should use std::set instead of std::unordered_map, eg:

string minWindow(string s, string t) {
    set<char> charFinder;
    for (int i = 0; i < t.length(); ++i) {
        charFinder.insert(t[i]);
    }
    //
    // alternatively:
    // set<char> charFinder(t.begin(), t.end());

    cout << (charFinder.find(s[0]) == charFinder.end()) << endl;
    //
    // alternatively:
    // bool notFound = charFinder.find(s[0]) == charFinder.end();
    // cout << notFound << endl;
    //
    // alternatively:
    // cout << charFinder.contains(s[0]) << endl;

    return "hi";
}
0
votes

Problem is with this statement :

cout << charFinder.find(s[0]) == charFinder.end() << endl;

stream insertion operator, << has higher precedence than equality operator, ==.

The statement is same as :

((cout << charFinder.find(s[0])) == charFinder.end()) << endl;

The overloaded operator << of std::cout returns a reference to std::cout.

When compiler encounters that you are comparing a std::ostream object (std::cout) with an iterator which is returned by std::unordered_map.end() it issues an error as std::ostream does not have an overloaded operator == to compare itself with an iterator.