Modernes C++ programmieren

Okt 23, 2024

lst-0794-godb.cpp

//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/MWrY1cznd 
#include <unordered_set>
#include <iostream>
#include <vector>
#include <string>
using std::string; using std::unordered_set; using std::cout;
struct Word {
    string word_;
    size_t row_;
    Word(const string &word, size_t row)
        : word_{word}, row_{row} {}
    friend bool operator==(const Word& a, const Word &b)
        { return a.word_ == b.word_; } // ignoriert row
 };
 namespace std {
 template<> struct hash<Word> { // ignoriert row
        std::hash<string> stringHash;
        std::size_t operator()(const Word &w) const {
            return stringHash(w.word_);
        }
 }; }
 struct ExactWordHash { // bezieht row mit ein
     std::hash<string> sHash;
     std::hash<size_t> iHash;
     bool operator()(const Word& a) const {
         return sHash(a.word_) ^ iHash(a.row_);
     }
 };
 struct ExactWordEqual { // bezieht row mit ein
     bool operator()(const Word& a, const Word &b) const {
         return std::tie(a.word_, a.row_) == std::tie(b.word_, b.row_);
     }
 };
 int main() {
     std::vector input {
       Word{"eine",0}, Word{"Rose",0},
       Word{"ist",1}, Word{"eine",1}, Word{"Rose",1},
       Word{"ist",2}, Word{"eine",2}, Word{"Rose",2},  };
     // Überladungen nutzen
     unordered_set<Word> words( input.begin(), input.end() );
     cout << words.size() << '\n'; // Ausgabe: 3
     // Eigene Funktoren nutzen
     unordered_set<Word,ExactWordHash,ExactWordEqual> poem(
          input.begin(), input.end() );
     cout << poem.size() << '\n';  // Ausgabe: 8
     // Hash als Lambda
     auto h = [](const auto &a) { return std::hash<string>{}(a.word_); };
     unordered_set<Word,decltype(h)> rose(input.begin(), input.end(), 10, h);
     cout << rose.size() << '\n';  // Ausgabe: 3
 }