#include <string>
#include <iostream>

#include <unordered_set>

//key
class Key
{
    std::string d_name;
    std::string d_phone;

    public:
        Key(std::string const &name, std::string const &phone);
        bool operator==(Key const &other) const = default;

        std::string const &name() const;
        std::string const &phone() const;
};
//=

inline std::string const &Key::name() const
{
    return d_name;
}

inline std::string const &Key::phone() const
{
    return d_phone;
}

//KeyHash
struct KeyHash
{
    size_t operator()(Key const &key) const;        // noexcept;
};

size_t KeyHash::operator()(Key const &key) const    // noexcept
{
    std::hash<std::string> hashObj;

    return hashObj(key.name()) ^ (hashObj(key.phone()) << 1);
}
//=

//Hash
template<>
struct std::hash<Key>
{
    std::size_t operator()(Key const &key) const;           // noexcept;
};

size_t std::hash<Key>::operator()(Key const &key) const     // noexcept
{
    std::hash<std::string> hashObj;

    return hashObj(key.name()) ^ (hashObj(key.phone()) << 1);
}
//=

using namespace std;

Key::Key(string const &name, string const &phone)
:
    d_name(name),
    d_phone(phone)
{}

int main()
{
    Key k1{ "hello", "world" };
    Key k2{ "something", "else" };

    cout << (k1 == k1) << ' ' << (k1 == k2) << '\n';

    unordered_set<Key> keySet;
    unordered_set<Key, KeyHash> key2;

    keySet.insert(k1);
    keySet.insert(k2);

    cout << keySet.find(k1)->name() << '\n';
}
