Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do compilers allow an allocator of a different value type than the container used

It seems that the C++ STL container requirements are that the provided allocator type's value_type be the same as the STL container's value_type

Requires:allocator_- type::value_type is the same as X::value_type.

However, the following code that uses a vector of strings but with an allocator for doubles works just fine on VS 2012 and g++ 4.4.7. On g++, valgrind does not produce any errors either.

int main()
{
  typedef vector<std::string, std::allocator<double> > StringList;
  StringList s;
  for(int i=0; i < 100; i++){
    stringstream ss;
    ss << i;
    s.push_back(ss.str());
  }
  for(StringList::iterator it = s.begin(); it != s.end(); ++it)
    {
      cout << *it << " ";
    }
  cout << endl;

  return 0;
}

I'm assuming the allocator is being rebound internally to an allocator of the value_type of the container (though maybe I'm wrong).

My question is am I misreading the C++ spec and in fact all containers will always "rebind" the allocator provided to use the type they want? Or is that just a common practice but not guaranteed.

Essentially can I count on this "feature" that containers will always take whatever allocator I provide (of any type) and make it work for the value_type of that container?

like image 676
innocent_bystander Avatar asked May 22 '17 04:05

innocent_bystander


People also ask

What does an allocator actually need to do?

Allocators handle all the requests for allocation and deallocation of memory for a given container. The C++ Standard Library provides general-purpose allocators that are used by default, however, custom allocators may also be supplied by the programmer.

What is use of allocator in C++?

Allocators are used by the C++ Standard Library to handle the allocation and deallocation of elements stored in containers. All C++ Standard Library containers except std::array have a template parameter of type allocator<Type> , where Type represents the type of the container element.


1 Answers

If you try to build your code with clang/libc++ (adding the appropriate includes and using namespace std;, you get:

/Sources/LLVM/llvm/projects/libcxx/include/vector:474:5: error: static_assert failed "Allocator::value_type must be same type as value_type" static_assert((is_same::value),

Anyway, the standard is really clear on this (in c++11/14/1z - but not c++03):

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

So if you try to instantiate vector<std::string, std::allocator<double> >, you get undefined behavior - and "seems to work fine" is a particularly onerous version of undefined behavior. But really, it is "seems to work fine for now"

like image 173
Marshall Clow Avatar answered Sep 23 '22 07:09

Marshall Clow