Few small remarks.
When you write the following:
Code:
for (Pair p : pairs) {
You are creating a copy of each pair in the vector. In your case, those copies are not that expensive, but it's good to get into the habit of avoiding unnecessary copies.
For example, the following uses const references to avoid any copies:
Code:
for (const Pair& p : pairs) {
Similarly, your remove_pair() method can be changed as follows:
Code:
void remove_pair(const Pair& p)
And your 'rem' lambda as well:
Code:
const auto rem = [&] (const Pair& p)
Similar for the 'add' lambda.

The any_pair() method returns the first pair in the storage as a copy. Is this what you want?

The operator() in your Hash can also accept its parameter as const reference.
Same for the l and r parameters for operator() of Equal.

And same for reverse_pair(), its parameter can be a const reference.