2

Why doesn't this work?

template <typename T, typename U>  
class TSContainer {  
private:  
   U<T> container;  
};

called as:

TSContainer<int, std::vector> ts;

I think a solution might be:

template <typename T, template <typename> typename C>  
class TSContainer  
{  
        C<T> container;  
};

but that doesn't work either.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Jonathan Winks
  • 1,091
  • 2
  • 9
  • 12

2 Answers2

5

This is what you need:

#include <vector>
template <typename T, template<typename, typename> class C>  
class TSContainer  
{  
    C<T, std::allocator<T> > container;  
};

int main() {
  TSContainer<int, std::vector> a;
}

Note that std::vector takes two template parameters with the second being defaulted to std::allocator. Alternatively, you can write:

#include <vector>
template <typename T, template<typename, typename = std::allocator<T> > class C>  
class TSContainer  
{  
        C<T> container;  
};

int main() {
  TSContainer<int, std::vector> a;
}

Both of these force the selection of the allocator on you. If you want to control which allocator is used by your vector (i.e. what is used as second template parameter to C), you can also use this:

#include <vector>
template <typename T, template<typename, typename> class C, typename A = std::allocator<T> >  
class TSContainer  
{  
        C<T, A> container;  
};

int main() {
  TSContainer<int, std::vector> a;
}

This is the most flexible solution.

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
  • Ah, that explains it. Is there any specific reason you used class instead of typename there? I'm new to templates (as you've no doubt guessed), and not aware of the conventions. – Jonathan Winks Nov 09 '11 at 22:52
  • @JonathanWinks: `typename` and `class` are interchangeable in this context; some prefer `class`. – Lightness Races in Orbit Nov 09 '11 at 22:53
  • @JonathanWinks There's discussion and an answer about `typename` vs `class` here: [C++: Use 'class' or 'typename' for template parameters?](http://stackoverflow.com/questions/213121/c-use-class-or-typename-for-template-parameters) – AusCBloke Nov 09 '11 at 22:53
  • 1
    Actually, it must be `class`. Normally, wherever you write `typename` you can also write `class`, but if the keyword is preceded by `template`, it should read `class`. – Adam Zalcman Nov 09 '11 at 22:57
  • @Adam: That's the kind of information I was looking for, thank you! – Jonathan Winks Nov 09 '11 at 23:00
  • Default template-template parameter is required in the second version AFAIK: How would compiler know what `C` means if we did not specify the default for the second template-template parameter? – Adam Zalcman Nov 09 '11 at 23:09
  • @AdamZalcman: Well I never! to geordi: `{ Foo foo; } template > typename C> struct Foo { C container; };`, and back: `error: expected 'class' before 'C'`. Switching solves. `14.1/2` in n3290 (just about). Learnt something here today. Seems like a silly thing, though. – Lightness Races in Orbit Nov 09 '11 at 23:39
  • @Adam : My mistake, and I like your 3rd take best. :-] – ildjarn Nov 10 '11 at 00:50
1

Wouldn't it be much more easy to simply do something like:

#include <vector>
template <typename C>  
class TSContainer  
{  
    C container;  
};

int main() {
  TSContainer<std::vector<int> > a;
}
paul23
  • 8,799
  • 12
  • 66
  • 149