P.J. Plauger said:
Two considerations:
1) An allocator is often a zero-sized object. With proper
finagling, you can get it to occupy no space in each
vector object. Making it a static would then use *more*
space (however small), but also add a minor complication
to instantiating such a container in a DLL.
proper finagling? hmm...(had to look up the word in the dictionary)
2) An allocator that is not a zero-sized object may well
have writable storage, for maintaining a per-container
pool, for example. The standard containers are not required
to accept such allocators, but the C++ Standard encourages
implementations to do so. The Dinkum C++ Library accepts
them. ...
Aha! So std::allocator could have private state.
Then of course its a *big* difference whether you make it
static or not. Making it static could break the code. Correct?
So it's probably not a good idea to make allocators static
under two circumstances:
1) if allocators are zero-sized objects
2) if allocators are not zero-sized objects
The following little test seems to show that
non-static member takes space, but static does not.
(gcc under cygwin):
//------------------------------------------------------------------------
#include <memory>
#include <iostream>
using namespace std;
class small { int a; };
class big { int a[200]; };
class small_alloc {
small a;
allocator<small> alloc;
};
class small_alloc_static {
small a;
static allocator<small> alloc;
};
class big_alloc {
big a;
allocator<big> alloc;
};
class big_alloc_static {
big a;
static allocator<big> alloc;
};
int main(int argc, char *argv[]) {
cout << "size(alloc<small>)=" << sizeof(allocator<small>)
<< " size(alloc<big>)=" << sizeof(allocator<big>)
<< endl;
cout << "size(small)=" << sizeof(small)
<< " size(small_alloc)=" << sizeof(small_alloc)
<< " size(small_alloc_static)=" << sizeof(small_alloc_static)
<< endl;
cout << "size(big)=" << sizeof(big)
<< " size(big_alloc)=" << sizeof(big_alloc)
<< " size(big_alloc_static)=" << sizeof(big_alloc_static)
<< endl;
return 0;
}
//---------------------------------------------------------------
The result is:
size(alloc<small>)=1 size(alloc<big>)=1
size(small)=4 size(small_alloc)=8 size(small_alloc_static)=4
size(big)=800 size(big_alloc)=804 size(big_alloc_static)=800
From this i would conclude that:
1) the gcc std::allocator<T> is a zero-sized object.
(sizeof(allocator<T>) returns 1, but i cannot imagine it
really has 1 byte of private state.)
2) the static member alloc takes _no_ space, but the non-static does.
So I'd prefer to make it a static member, unless it breaks the code.
The result could also mean that gcc cannot do "proper finagling"
(whatever that means...would you care to explain?)
I won't comment on whether it would be better *style* to
do so.
No need to comment on style.
I am coming form the traditional malloc/free() world,
*one* global allocator for *all* types of objects.
Thanks very much for your technical explanations,
which help me to better understand what a C++ std::allocator is.
Bernhard Kick.