Templated class template declarations

Started by
19 comments, last by Timkin 18 years, 4 months ago
I read somewhere - most likely C++ Templates - that templated classes can be used/written/declared in the template declaration itself. I.e. they could be declared with their own independent types that are separate from the rest of the template declaration. Unfortunately, I've forgotten both how to do it and what such a thing is called (thus Google hasn't been helpful). Here's a small (and incorrect) example to demonstrate what I mean :

// this compiles fine
template<typename T, template<typename T2> class C>
class Foo { /* */ };

// as does this ... for obvious reasons
template<typename T>
class Bar { /* */ };

// unfortunately, this spawns an error in VS8
// error C3200: 'Bar<T>' : invalid template argument for template parameter 'C',
//     expected a class template
Foo< int, Bar<int> > foo;


What am I missing ? Any help would be greatly appreciated. <edit :: fixed source tags
- stormrunner
Advertisement
It's just
Foo< int, Bar > foo;
Bar<int> isn't a template, it's an instantiation of a template. Change that last line to
Foo< int, Bar > foo;
and it should compile.
Thank you, both of you, but I'm still a bit confused. In the line
Foo<int, Bar>

shouldn't it be specified exactly what type Bar should be ?

In the same vein, say I have the aforementioned declarations, except Foo now has a member variable Bar<T>. If I try to assign it to something ( a concrete Bar<T> object ) it won't compile
template< typename T, template< typename T2 > class C >class Foo{    private:       C    _foobar;    public:       Foo( C foobar )          : _foobar( foobar )       { }};// use it ...Bar<int> bar;Foo< int, Bar > foo( bar );

VS8 informs me that "the argument list for template template parameter 'C' is missing", along with a hefty amount of excessive gibberish.
- stormrunner
In Foo Bar is a template template parameter so you need to instantiate the template. ex:
template< typename T, template< typename T2 > class C >class Foo{    private:       C<T>    _foobar;    public:       Foo( C<T> foobar )          : _foobar( foobar )       { }};
Thanks again, SiCrane, that solved my problem and cleared up the main point I was confused on. However, is there no way to simply pass the type with the declaration ? In my original example, I meant for C<T2> to be independant of T. So I could have something like Foo<int, Bar<std::string> >.
- stormrunner
Sure just use a normal type argument.
template <typename T1, typename T2>class Foo {  // blah blah blah};
Quote:Original post by stormrunner
Thanks again, SiCrane, that solved my problem and cleared up the main point I was confused on. However, is there no way to simply pass the type with the declaration ? In my original example, I meant for C<T2> to be independant of T. So I could have something like Foo<int, Bar<std::string> >.

template< typename T, template< typename > class C, typename T2 >class Foo { ... };   ...Foo< int, Bar, std::string> foobar;

That's somewhat of a pain, though.
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid
template <typename c1, typename c2> class chicken{}; template <typename c1> class zebra{}; // in mainchicken<int, zebra<std::string> > my_chicken;

Should work dandily.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
whats wrong with ...
template < typename T, template < typename T2 > typename C<T2> >class Foo{...};template <typename T>class Bar{...};Foo< int, Bar<std::string> >


?

This topic is closed to new replies.

Advertisement