Search code examples
c++stlcontainersallocator

Allocators: how are the standard containers expected to work internally?


As an example for this question, I'll use std::vector.
Its definition from the documentation follows:

template<class T, class Allocator = std::allocator<T>>
class vector;

As expected, if T is its type, the allocator should be biased towards T.
Anyway, the code below compiles with no errors (at least, using GCC) and runs:

#include<vector>
#include<memory>
#include<string>

struct S {
    int i;
    double d;
    std::string s;
};

int main() {
    std::allocator<int> alloc;
    std::vector<S, std::allocator<int>> v{alloc};
    v.push_back(S{});
}

Here, I'm creating a vector of S by using an allocator focused on int.

Is it legal code? Should I expect undefined behavior? What else?
I don't fully understand what the magic behind that and why the STL lets the users do that.
On the other side, things like rebind are mentioned only in the documentation of std::list and I don't know if they are meant also for such a case.

In other therms, if it works I'd like to know why it works (is it rebind behind that?), otherwise I'd like to know why it is allowed.


Solution

  • Table 98 -- Allocator-aware container requirements says in its first row:

    Requires: allocator_type::value_type is the same as X::value_type

    Violation of a Requires clause by the client code results in undefined behavior.

    gcc and VS do not detect this error. They allow the code to work by rebinding the allocator to the appropriate type. libc++ actively detects this error with a static_assert.

    http://melpon.org/wandbox/permlink/LVYEHfVIGoyZsii8

    All three implementations of vector are valid in this regard.

    The rationale for the libc++ active detection of this error is to find your errors for you faster (and at compile time). It would be a bad thing if in a large program you had two vectors: vector<int, some_allocator<int>> and vector<int, some_allocator<long>> and the program logic assumed these were the same type.