Topic: Article: allocators...exceptions...new/delete [reply to: Sat, 12Jul 2003 09:24:06 -0400, Richard Smith].


Author: richard@ex-parrot.com ("Richard Smith")
Date: Thu, 17 Jul 2003 15:17:32 +0000 (UTC)
Raw View
"Dhruv Matani" <dhruvbird@gmx.net> wrote in message
news:1058347888.3149.18.camel@home.free...
> What I had in mind was something like this:
>
> #include <memory>
> #include <nstl/list_alloc.hpp>

I assume this is the one from
http://www.geocities.com/dhruvbird/nstl0.2.zip. For the benefit of anyone
else reading this thread, list_node_allocator is a stateless allocator
declared as follows.

  namespace nstd {
    template <class T>
    class list_node_allocator;
  }

> #include <boost/pool/pool.hpp>

Let me quote the declaration of fast_pool_allocator:

  namespace boost {
    template <class T,
              class UserAllocator = /* default value */,
              class Mutex = /* default value */,
              unsigned NextSize = 32>
    class fast_pool_allocator;
  }

Note in particular the extra template parameters.

> template <template <class type> class some_alloc >
> struct foo {
>   //type t;
>   some_alloc<int> ia;
> };

The template argument to foo must be a class template with one template
parameter.

> int main ()
> {
>   foo <nstd::list_node_allocator> f;

This is fine: list_node_allocator is a class template with one template
parameter.

>   foo <boost::fast_pool_allocator> f1;

This is not legal: fast_pool_allocator is a class template with four
template parameters.  The fact that the last three have default values is
irrelevant.  There is a core language defect report (DR150) about this. See

  http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#150

for more details.  Some compilers do accept this code, but you must bear in
mind that it is not strictly legal.  Unless this is resolved (and I hope it
will be in C++0x), this is one reason why allocators don't work too well as
template template parameters.

> That would eliminate the need to pass the type explicitly, and also, the
> rebind hack would disappear in case of a list, or the map, etc......

I agree, this would have been nice, but I think it's too late now.

> Now, it would be great if this would work:
>
> #include <memory>
> #include <nstl/list_alloc.hpp>
> #include <boost/pool/pool.hpp>
>
> template <template <class type> class some_alloc<type> > //NOTE.
> struct foo {
>   //type t;
>   some_alloc<type> ia;
> //now, if you want a node allocator, just do:
> //some_alloc<node_struct> na;
> };

The way to do this with the current allocator framework would to introduce a
typedef for the node allocator:

  template <class Alloc> struct foo {
    typedef typename Alloc::template rebind<node_struct>::other
node_allocator;

It's a bit of a mouthful, and explaining to novices precisely what that
"template" keyword is doing in the middle can be a bit difficult.

> int main ()
> {
>   foo <nstd::list_node_allocator<int> > f; //NOTE.
>   foo <boost::fast_pool_allocator<int> > f1; //NOTE.
> }
>
>
> I'm not too sure about whether the code is even correct. Please tell me
> if
> it's correct, because I don't trust g++ much on template issues.

No.  Your code is illegal for two reasons.  First the declaration of foo is
syntactically incorrect.  You have:

  template <template <class type> class some_alloc<type> > //NOTE.
  struct foo {

1.  If you want foo to have one template parameter that is a class, you must
write

  template <class Alloc> struct foo;
  foo< nstd::list_node_allocator<int> > f;

2.  If you want it to have one template parameter that is a template class,
you must write something like the following, but making sure you give the
template template parameter the correct number and types of arguments

  template <template <class> class Alloc> struct foo;
  foo< nstd::list_node_allocator > f;

3.  If you want both a type (int) and a template (e.g.
nstd::list_node_allocator), you must give the template two parameters:

  template <class Type, template <class> class Alloc> struct foo;
  foo< int, nstd::list_node_allocator > f;

Only the first of these solves the problem of allocators with additional
template parameters, and brings us back to rebind.  You cannot do anything
like akin to template parameter deduction on function calls, which seems to
be what you're trying to do.

> Something that I'm quite sure about is that the boost allocator example
> (f1 object thing) does not compile because of the the n number of
> parameters that it has.

Correct.  See above.

> One more thing: Is it legal to access 'type' within the struct, as in,
> can you do something like this inside the struct:
> some_alloc<type> alloc;
>
> It doesn't seem to work on g++.

As indeed it shouldn't.  You're code is syntactically incorrect, and
shouldn't compile even with nstd::list_node_allocator.  Instead, you should
either use Alloc::value_type (if you're using solution 1), or just use Type
(if you're using solution 3).   If you use solution 2, you cannot get at the
type at all.

--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]