开发者

How to instantiate with other than defaulted parameters in a template template parameter

I'm trying to cement my understanding of template template parameters. In C++ Templates the Complete Guide (Vandervoorde, Josuttis), they have an example on page 52 that I want to use as indicated in this image:

How to instantiate with other than defaulted parameters in a template template parameter

(I'm also trying to learn how to use images from Picasa on stackoverflow so if the above doesn't work, here's a slightly more verbose version)

Original Code from Book

template <typename T,
          template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class CONT=std::vector>
class Stack
{
    private:
        CONT<T >  elems; //Why doesn't CONT<T, ALLOC> elems; compile?
};

The don't show you how to use this for a different allocator. They do show a different conta开发者_开发技巧iner as:

Stack<int, std::deque> my_deque_stack;

and in my naivete I tried:

Stack<int, std::deque<int,  std::allocator<int> >  > my_deque_int_stack;

I also tried in the private section defining CONT as

CONT<T, ALLOC>

but that too generates a compiler error. I'm wondering what the correct syntax is for using the Stack template where I want to use a deque but want to specify a different allocator. I read some similar posts here that indicate sprinkling typename or template qualifiers around and I tried a couple but couldn't seem to find the magic formula.


The parameter definitions inside CONT are actually not used by the compiler. The template-template parameter CONT is actually similar to a function, which takes 2 types input and return a new type:

// pseudo code
type Stack(type T, type(*CONT)(type ELEM, type ALLOC = etc)) { 
   return CONT(T);
}

and like the normal function pointer declarations, the names ELEM, ALLOC are actually ignored by the compiler.

What the compiler sees would be just

template <typename T,
          template <typename E, typename = std::allocator<E> > class CONT = std::vector>
struct Stack { ... };

Therefore, you cannot use ALLOC at all.


So to solve it? Well, you pass an extra parameter! Just like the case in a normal C++ function:

// pseudo code
type Stack(type T, type(*CONT)(type, type), type ALLOCATOR = etc) { 
//                                          ^^^^^^^^^^^^^^^^^^^^
   return CONT(T, ALLOCATOR);
}

The corresponding actual template declaration would be

template <typename T,
          template <typename, typename> class CONT = std::vector,
          typename ALLOCATOR = std::allocator<T> >
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct Stack {
   ...
   CONT<T, ALLOCATOR> elems;
};

//...
Stack<int, std::vector, std::allocator<int> > s;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜