You can give `unordered_map` a specific `hash` and `equals` function as a template parameter, so you don't have to specialize `std::hash`. Which the compiler probably wouldn't even let you do, because it's already specialized.

    class CollisionFilter {

        using CollisionId = std::pair<EntityId, EntityId>;

        struct IdHash {
            std::size_t 
            operator() (
                const CollisionId& collisionId
            ) const;
        };

        struct IdEquals {
            bool
            operator() (
                const CollisionId& lhs,
                const CollisionId& rhs
            ) const;
        };

        using CollisionMap = std::unordered_map<CollisionId, Collision, IdHash, IdEquals>;
 
    // ...
};