allocator requirements

J

John Harrison

If you specify an allocator in an STL container is it a requirement that
the allocator allocates object of the right type, or can you assume that
the container will rebind the allocator to the correct type?

For example I tried the following code which uses a 'wrong' allocator and
was slightly surrised to find it compiles on the three compilers I tried
it on

#include <vector>
#include <memory>

int main()
{
std::vector<int, std::allocator<double> > vec;
vec.push_back(1);
}

john
 
V

Victor Bazarov

John said:
If you specify an allocator in an STL container is it a requirement
that the allocator allocates object of the right type, or can you
assume that the container will rebind the allocator to the correct type?

It's quite possible that the container uses 'construct' member
function, which accepts the memory of any type (for placement
new) and double* is good enough for int values to be constructed
in. You probably get some excessive memory use that way, but
not any serious problem. Try it in reverse, have a vector of
double and use allocator<char> just for kicks...

As to 'rebind', I can't find any reference to it in the chapter
on containers. Assume you can, rely upon... I wouldn't.
For example I tried the following code which uses a 'wrong' allocator
and was slightly surrised to find it compiles on the three compilers I
tried it on

#include <vector>
#include <memory>

int main()
{
std::vector<int, std::allocator<double> > vec;
vec.push_back(1);
}

V
 
J

John Harrison

It's quite possible that the container uses 'construct' member
function, which accepts the memory of any type (for placement
new) and double* is good enough for int values to be constructed
in. You probably get some excessive memory use that way, but
not any serious problem. Try it in reverse, have a vector of
double and use allocator<char> just for kicks...

As to 'rebind', I can't find any reference to it in the chapter
on containers. Assume you can, rely upon... I wouldn't.


V

As a corrolary I tried the following

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

typedef std::vector<int, std::allocator<double> >::allocator_type X;

void test(std::allocator<double> const&)
{
std::cout << "double\n";
}

void test(std::allocator<int> const&)
{
std::cout << "int\n";
}

int main()
{
test(X());
}

What would you expect the output to be, 'int' or 'double'? Both compilers
I tried it on the output was 'int'. Which means those versions of the STL
are rebinding the allocator to be an int allocator.

john
 
J

Jonathan Turkanis

John Harrison said:
If you specify an allocator in an STL container is it a requirement that
the allocator allocates object of the right type, or can you assume that
the container will rebind the allocator to the correct type?

I think this is addressed by 23.1 [lib.container.requirements] para.
8:

Copy constructors for all container types defined in this clause copy
an allocator argument from their
respective first parameters. All other constructors for these
container types take an Allocator& argument
(20.1.5), an allocator whose value type is the same as the container's
value type.

Jonathan
 
J

John Harrison

Yes, according to the C++ Standard.


Yes, according to widespread practice.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com

Yes it seems so, both implementations of the STL I've checked do rebind
the allocator for vector at least. This seems to directly contradict the
requirements for allocator_type.

I also noticed that Josuttis' book also ignores what the standard says,
see first page of chapter 15 where he happily passes the same allocator to
several containers with different value types.

What's the reason for the standard saying what it does? It seems a bit
inconvenient.

john
 
J

Jonathan Turkanis

John Harrison said:
Yes it seems so, both implementations of the STL I've checked do rebind
the allocator for vector at least. This seems to directly contradict the
requirements for allocator_type.

How does this contradict the allocator requirements?
I also noticed that Josuttis' book also ignores what the standard says,
see first page of chapter 15 where he happily passes the same allocator to
several containers with different value types.

It looks to me like the allocators he uses all have value_types
appropriate for the containers.

Jonathan
 
J

John Harrison

John Harrison said:
How does this contradict the allocator requirements?

Not the allocator requirements, the requirements for allocator_type. For
instance 23.2.4 has

template <class T, class Allocator = std::allocator<T> >
class vector
{
...
typedef Allocator allocator_type;

i.e. allocator_type should be the same type as the template parameter.
It looks to me like the allocators he uses all have value_types
appropriate for the containers.

Well maybe I'm reading too much into this but in chpater 15 in quick
succession he gives

vector<int,SpecialAlloc> v;

map<int,float,less<int>,SpecialAlloc> m;

basic_string<char,char_traits<char>,SpecialAlloc> s;

Its not specified anywhere what SpecialAlloc is but by the quote you made
from the standard it cannot have the correct value type for all these
different containers.

john
 
P

P.J. Plauger

Yes it seems so, both implementations of the STL I've checked do rebind
the allocator for vector at least. This seems to directly contradict the
requirements for allocator_type.

I think this approach gives meaning to an otherwise ill formed program,
hence it's a conforming implementation.
I also noticed that Josuttis' book also ignores what the standard says,
see first page of chapter 15 where he happily passes the same allocator to
several containers with different value types.

What's the reason for the standard saying what it does? It seems a bit
inconvenient.

It was simple, and the rebind mechanism was introduced as a cutesy
trick before template template was well established in the language.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
J

Jonathan Turkanis

John Harrison said:
Not the allocator requirements,

Sorry, I read your post too fast.
the requirements for allocator_type. For
instance 23.2.4 has

template <class T, class Allocator = std::allocator<T> >
class vector
{
...
typedef Allocator allocator_type;

i.e. allocator_type should be the same type as the template
parameter.

I still don't see the violation.
Well maybe I'm reading too much into this but in chpater 15 in quick
succession he gives

vector<int,SpecialAlloc> v;

map<int,float,less<int>,SpecialAlloc> m;

basic_string<char,char_traits<char>,SpecialAlloc> s;

That's funny. My copy has

vector<int, MyAlloc<int> > v;
map<int,float,less<int>,MyAlloc<std::pair<const int, float> > > m;
...

Jonathan
 
V

Victor Bazarov

Jonathan said:
news:eek:psav1xfa5212331@andronicus... [...]
I also noticed that Josuttis' book also ignores what the standard

says,

see first page of chapter 15 where he happily passes the same

allocator to

several containers with different value types.

It looks to me like the allocators he uses all have value_types
appropriate for the containers.

Well maybe I'm reading too much into this but in chpater 15 in quick
succession he gives

vector<int,SpecialAlloc> v;

map<int,float,less<int>,SpecialAlloc> m;

basic_string<char,char_traits<char>,SpecialAlloc> s;


That's funny. My copy has

vector<int, MyAlloc<int> > v;
map<int,float,less<int>,MyAlloc<std::pair<const int, float> > > m;
...

<Butting in...>

So does mine, but it's the 7th printing (what's yours?) so, either
before they printed something differently or after...

V
 
J

Jonathan Turkanis

Victor Bazarov said:
<Butting in...>

So does mine, but it's the 7th printing (what's yours?) so, either
before they printed something differently or after...

Mine is the 10th. I wonder if Josuttis changed it because he decided
it was an error or because he thought it was debatable or an
unnecessary distraction.

I'm a bit suprised that the requirement that the value_type's match is
stated clearly for basic_string (21.3/1) but only in an almost
parenthetical way for containers generally (23.1/8), AFAICT.

Jonathan
 
J

John Harrison

Mine is the 10th. I wonder if Josuttis changed it because he decided
it was an error or because he thought it was debatable or an
unnecessary distraction.

Mine's the third, the change is listed in the errata on his website.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top