what is the use of vector::get_allocator?

What is the use of get_allocator ?? I've read a program from this site, but I couldn't understand the 15th line. What is myvector.get_allocator().construct(&p[i],i) ??

and where is this get_allocator used?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  // vector::get_allocator
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;
  int * p;
  unsigned int i;

  // allocate an array with space for 5 elements using vector's allocator:
  p = myvector.get_allocator().allocate(5);

  // construct values in-place on the array:
  for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],i);

  std::cout << "The allocated array contains:";
  for (i=0; i<5; i++) std::cout << ' ' << p[i];
  std::cout << '\n';

  // destroy and deallocate:
  for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]);
  myvector.get_allocator().deallocate(p,5);

  return 0;
}
Last edited on
> What is myvector.get_allocator().construct(&p[i],i) ??

See: http://en.cppreference.com/w/cpp/memory/allocator/construct

Note that this kind of code is deprecated in C++17
(The canonically correct way to access an allocator's functionality is through std::allocator_traits.)


> where is this get_allocator used?

Most of the use-cases for a container's get_allocator() are somewhat esoteric.
If you are somewhat new to C++, you may want to ignore this for now.

Here is an example where get_allocator() could be used in a sensible manner:
(Caveat: the GNU compiler chokes on this)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <vector>
#include <type_traits>
#include <iostream>

template< typename T, typename A >
void safe_swap( std::vector<T,A>& a, std::vector<T,A>& b )
{
    // If std::allocator_traits<allocator_type>::propagate_on_container_swap::value is true,
    // then the allocators are exchanged using an unqualified call to non-member swap.
    // Otherwise, they are not swapped
    // (and if get_allocator() != other.get_allocator(), the behavior is undefined).
    // http://en.cppreference.com/w/cpp/container/vector/swap

    if( ( std::allocator_traits<A>::propagate_on_container_swap::value ) ||
        ( a.get_allocator() == b.get_allocator() ) )
    {
        // ok, swap the allocators if required, no copy or move of elements in the vectors
        a.swap(b) ;
        std::cout << "swapped using std::vector<>::swap\n" ;
    }

    else
    {
        // avoid undefined behaviour: implement swap by moving the elements
        const auto temp( std::move(a) ) ; // EDIT: ???

        // Move assignment operator. Replaces the contents with those of other using move semantics
        // (i.e. the data in other is moved from other into this container).
        // If std::allocator_traits<allocator_type>::propagate_on_container_move_assignment()
        // is false (it is false here, or the else clause would not have been entered into)
        // and the source and the target allocators do not compare equal (they do not compare equal here),
        // the target cannot take ownership of the source memory and must move-assign each element individually
        // http://en.cppreference.com/w/cpp/container/vector/operator%3D
        a = std::move(b) ;
        b = std::move(temp) ;
        std::cout << "swapped by moving the elements;\n\t\t"
                     "(allocators aren't equal and they can't be swapped)\n" ;
    }
}

struct my_allocator : public std::allocator<int>
{
    using std::allocator<int>::allocator ;

    static constexpr bool is_always_equal = false ;
    static constexpr bool propagate_on_container_move_assignment = false ;
    friend bool operator== ( const my_allocator&, const my_allocator& ) { return false ; }
    friend bool operator!= ( const my_allocator&, const my_allocator& ) { return true ; }
};

int main()
{
    {
        std::cout << "std::vector with the default allocator: " ;
        std::vector<int> a(100), b(200) ;
        safe_swap(a,b) ;
    }

    {
        std::cout << "\nstd::vector with the my_allocator: " ;
        std::vector< int, my_allocator > a(100), b(200) ;
        safe_swap(a,b) ;
    }
}

std::vector with the default allocator: swapped using std::vector<>::swap

std::vector with the my_allocator: swapped by moving the elements;
		(allocators aren't equal and they can't be swapped)

http://coliru.stacked-crooked.com/a/73efad961c7ffe6d
http://rextester.com/AEND10373
Last edited on
Thank you for the reply :)
Topic archived. No new replies allowed.