Operandi non validi per l'espressione binaria quando si utilizza unordered_map?

Sep 09 2020

Sto cercando di scoprire se la mia tabella hash dei caratteri contiene il primo carattere di una stringa:

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";
}

Ma ottengo questo errore per qualche motivo. Questo non ha alcun senso per me. Qualcuno ha qualche idea?

Riga 8: Char 14: errore: operandi non validi nell'espressione binaria ('std::ostream' (aka 'basic_ostream<char>') e '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: :valore>'))
        cout << charFinder.find(s[1]) == charFinder.end() << endl;
        ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/cstddef:124:5:
nota: modello di funzione candidato non valido: nessuna conversione nota da 'std::ostream' (aka 'basic_ostream<char>') a 'std::byte' per il 1° argomento
    operatore<<(byte __b, _IntegerType __shift) noeccetto
    ^

Ho tagliato il resto del lungo messaggio di errore.

Risposte

1 RemyLebeau Sep 09 2020 at 01:05

Per Operator Precedence , operator<<ha una precedenza maggiore di operator==, quindi la tua coutespressione:

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

Viene valutato come se lo avessi scritto in questo modo:

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

L'errore del compilatore si lamenta di passare lo std::unordered_mapstesso a operator<<, che non è quello che intendevi. Osserva il messaggio di errore più attentamente, è esattamente ciò che sta sottolineando. Non c'è niente operator<<che std::ostreamprenda un std::unordered_mapcome input.

Per risolvere questo problema, devi usare esplicitamente le parentesi per dire al compilatore cosa vuoi veramente, ad esempio:

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

Altrimenti, usa boolinvece una variabile:

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

In C++ 20 puoi usarestd::unordered_map::contains() invece usare:

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

Detto questo, dal momento che in realtà non stai utilizzando affatto il conteggio dei caratteri, dovresti usarlo std::setinvece distd::unordered_map , ad esempio:

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";
}
Omkar76 Sep 09 2020 at 01:25

Il problema è con questa affermazione:

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

operatore di inserimento del flusso, <<ha una precedenza maggiore rispetto all'operatore di uguaglianza, ==.

L'affermazione è la stessa di:

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

L'operatore sovraccarico<< di std::coutrestituisce un riferimento a std::cout.

Quando il compilatore rileva che stai confrontando un std::ostreamoggetto ( std::cout) con un iteratoroggetto restituito da std::unordered_map.end(), emette un errore poiché std::ostreamnon dispone di un operatore sovraccarico ==per confrontarsi con un iterator.