this question follows from my previous one: Why shouldn't C++ operator new/delete/variants be in header files?. To quickly summarize, I'm learning about overriding global operator new, delete, etc. I now have need for a custom allocator class (my overloaded operator new calls std::set::insert(...), which seems to itself call new, thus infinite recusion). I think that if I supply a custom allocator (that, for example, uses malloc instead of new) to my std::set I can bypass the infinite recursion.
I've done some reading about implementing custom allocators, and am a bit confused by the semantics of struct rebind.
There is a good Q&A here: Parsing allocator::rebind calls, but I'm confused by one particular item still. cplusplus.com says about struct rebind:
Its member type other is the equivalent allocator type to allocate elements of type Type
I don't understand how other is a member of struct rebind. The definitions for struct rebind I've found look like:
template <class Type> struct rebind {
  typedef allocator<Type> other;
};
I don't see how other is a member variable of struct rebind. It's just typedefed. If I did typedef int foo; in the global namespace, that doesn't mean there's a global variable of type int declared in the global namespace, so in turn, how does other become a member of struct rebind?
By the way, I know (or at least I've read that) this has all been simplified post C++11, but I'd still like to understand this first, so that I have my fundamentals down. Thanks for any help.
While on this topic, can someone also explain the deal with typedefing within a struct? I've seen it once before in this amazing example from answerer Johannes Schaub, but I don't fully grok it yet. To me it looks like it's restricting the scope of the typedef to within an instance of the containing struct.
UPDATE:
I'd like to add this to my question. Using this abridged example from cppreference.com:
#include <memory>
#include <iostream>
#include <string>
int main()
{
    std::allocator<int> a1; // default allocator for ints
    decltype(a1)::rebind<std::string>::other a2_1;
}
Isn't the line decltype(a1)::rebind<std::string>::other a2_1; a long way of saying std::allocator<std::string> a2_1; ?
 
     
    