C++ Template Question

Started by
5 comments, last by PolyVox 12 years, 11 months ago
Hi Guys, the following is not valid C++:

#include <list>

template <typename ContainerType, typename ElementType>
class MyClass
{
public:
ElementType mSingleElement;
ContainerType<ElementType> mContainerOfElements;
};

int main(int argc, char* argv[])
{
MyClass<std::list, int> myClass;
return 0;
}


In particular, it complains about the line:

ContainerType<ElementType> mContainerOfElements;

With the error message:

error C3203: 'list' : unspecialized class template can't be used as a template argument for template parameter 'ContainerType', expected a real type[/quote]

I can get around this by writing it as follows:

#include <list>

template <typename ContainerType, typename ElementType>
class MyClass
{
public:
ElementType mSingleElement;
ContainerType mContainerOfElements;
};

int main(int argc, char* argv[])
{
MyClass<std::list<int>, int> myClass;
return 0;
}


This works, but it feels ugly to me that I have to specify 'int' twice in the following line:

MyClass<std::list<int>, int> myClass;

Is there are better way to write this?
Advertisement
You can use template templates:


#include <list>

template <template<typename, typename> class ContainerType, typename ElementType>
class MyClass
{
public:
ElementType mSingleElement;
ContainerType<ElementType, std::allocator<ElementType> > mContainerOfElements;
};

int main()
{
MyClass<std::list, int> myClass;
return 0;
}


*shudder*

Actually, the code isn't strict standards conforming because IIRC implementations have leeway to add additional template parameters to things like std::list as long as a default template argument is specified.

A better alternative, perhaps is to do this:


#include <list>

template <typename ContainerType>
class MyClass
{
public:
typedef typename ContainerType::value_type ElementType;
ElementType mSingleElement;
ContainerType mContainerOfElements;
};

int main()
{
MyClass<std::list<int> > myClass;
return 0;
}
Yes there is: template template parameters


template < template<typename X> class C, typename T>


Where 'typename X' is just the same declaration as any other template so it could have multiple parameters.

As always with templates though you may be hampered by whatever compiler you're using.

--Russell Aasland
--Lead Gameplay Engineer
--Firaxis Games

Thanks guys, that's awesome. I'll give this a go.

Actually, the code isn't strict standards conforming because IIRC implementations have leeway to add additional template parameters to things like std::list as long as a default template argument is specified.


Actually that's ok, the std::list was just an example for simplicity. In practice I'm using my own image class templatised on pixel type.

A better alternative, perhaps is to do this:


#include <list>

template <typename ContainerType>
class MyClass
{
public:
typedef typename ContainerType::value_type ElementType;
ElementType mSingleElement;
ContainerType mContainerOfElements;
};

int main()
{
MyClass<std::list<int> > myClass;
return 0;
}



Quoted for emphasis. The container type that you'll end up using already knows what its element type is, so the way to get around the redundancy is not to synthesize the container type from the element type, but to ask the container type for the element type.

Actually that's ok, the std::list was just an example for simplicity. In practice I'm using my own image class templatised on pixel type.
Ah so you're using pixel policies! You might want to check out mine for comparison: http://homepages.ihug.co.nz/~aurora76/Malc/Useful_Classes.htm
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

[quote name='PolyVox' timestamp='1304112180' post='4804562']
Actually that's ok, the std::list was just an example for simplicity. In practice I'm using my own image class templatised on pixel type.
Ah so you're using pixel policies! You might want to check out mine for comparison: http://homepages.ihu...ful_Classes.htm
[/quote]
Kind of... I was actually simplifying (again). It's a volume class templatised on voxel type. But you have some very interesting code snippets on your website, I'll have a look at those more closely.

This topic is closed to new replies.

Advertisement