Parsing the mailing

I am just good with C ++ distributions and I am trying to understand the purpose struct rebind

in each distributor. For example, in this program :

#include <memory>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef vector<int>::allocator_type IntAlloc;
int main( ) 
{
   IntAlloc v1Iter;
   vector<int> v1;

   //************What going on here?********
   IntAlloc::rebind<char>::other::pointer pszC =
      IntAlloc::rebind<char>::other(v1.get_allocator()).allocate(1, (void *)0);

   int * pInt = v1Iter.allocate(10);
}

      

I'm trying to figure out what the key line is doing. Does it typedef

IntAlloc

change the server now as a distributor for char

vector

? Even if I guessed correctly, I'm not sure I can break this. Here's my guess:

IntAlloc::rebind<char> //accessing the struct rebind

`::other` //accessing data member other inside rebind

(v1.get_allocator()) //**isn't this just retrieving IntAlloc in its original form?** 
///What is this for?

.allocate(1, (void *)0); //**this is allocating something? What do these parameters mean?**

      

+3


source to share


2 answers


This is all that was done before the start of C ++ 11 Allocator, they greatly simplified the situation with the 2011 standard.

struct rebind

is essentially a way to get around the fact that the language doesn't have templated typedefs that are needed Container

that don't allocate the same type internally like the allocator you pass them. They "rebuild" the allocator and return a new allocator that can allocate a different type (for example, "std :: set allocates some type" Node "that has pointers to other nodes for the tree structure, in addition to an object of the type that allocates your allocator) This mechanism hides the internal structure, but is sure that it is not.

So, for example, you may have Allocator<int>

, but to create a tree structure, std::set

you need to extract from an object of type Allocator<std::_Node<int>>

or something. The mechanism rebind

allows this.



(v1.get_allocator ()) // isn't it just getting IntAlloc in its original form?

This gets the allocator object from v1

which is of type vector<int>::allocator_type

, so more or less yes.

IntAlloc::rebind<char>::other(v1.get_allocator())

receives a distributor char

and initializes it to use the distributor of vector<int>

, v1

.

0


source


These lines

IntAlloc::rebind<char>::other::pointer pszC =
      IntAlloc::rebind<char>::other(v1.get_allocator()).allocate(1, (void *)0);

      

will use the same allocator used by v1

(a std::vector<int>

) to allocate one char

(near the address if possible 0x0

) But the allocator used by std :: vector actually knows how to allocate and build int

, not char

so you need to "rebuild" the type allocator to allocator char

(then you use the static allocate method and implicitly convert [build allocator char

from] your allocator int

v1.get_allocator()

to allocatorchar



)

Thus, if your allocator actually provided blocks of memory from an already allocated pool of memory (for example), you can reuse the same pool for different types.

See this and ./p> for details

0


source







All Articles