Disclamer: I know, that using std::map solves this problem, but it is not very clean to initialize.
The problem:
Imagine you have an array of large PODs which are rather expencive copy:
struct large_pod
{
   size_t id;
// a lot of members
};
So one would want to use a mapping to an intermediate associative container of pointers/references to large_pod in order to reduce algorithim complexity when searching.
std::vector<large_pod> original{};
std::vector<size_t> ids = ids_to_work_on();
// would rather have an std::set
auto queryMap = map_by<large_pod::id>(original);
for (const auto &i : ids)
{
   auto& pod = queryMap.find(i); // this will not compile, because T is not the same as Key, which is large_pod
}
So I wonder, why doesn't std::set allow to use something other than the Key if the Compare will compile?
struct compare_id
{
  // basic case
  bool operator()(const large_pod& lhs, const large_pod& rhs) const
  {
     return lhs.id < rhs.id;
  }
  // special cases
  bool operator()(const large_pod& pod, size_t id) const
  {
     return pod.id < id;
  }
  bool operator()(size_t id, const large_pod& pod) const
  {
     return id < pod.id;
  }
};
Of course, using std::map<size_t, const large_pod*> would work, but it requires explicit initialization and introducing redundancy (map[pod.id] = &pod);
