Template parameter depending on another one

A

Arne Claus

Hi
I got a headache on this problem, maybe someone can help me here
I want to create a class which can be handled like this

manager<int, list> // possible variant
manager<int, vector> // another possible variant
manager<float, vector> // and so on

I cannot just create / pass a vector<int>. I need the first information
(e.g. int) inside the manager class, because I wrap this type inside
another template (see below)
The problem is - how do I define such a template? My first Idea was
"leave it to the compiler"

template <class tContent, class tContainer> class manager {

void add(anotherBase<tContent>);

protected:
tContainer<anotherBase<tContent> > m_container;
};

which does not work, because "tContainer is not a template".
So my question - is this possible at all? I did not find anything on
that topic in "The C++ Programming Language", and that's a IMHO a bad
sign ...
Maybe someone knows another way of doing such a thing (derivation would
be possible, but ugly in this case).

Arne
 
F

Fraser Ross

I think you are not using the keyword typename when using a dependent type
name. If you still have a problem then post again.

Fraser.
 
D

Dan Cernat

Arne said:
Hi
I got a headache on this problem, maybe someone can help me here
I want to create a class which can be handled like this

manager<int, list> // possible variant
manager<int, vector> // another possible variant
manager<float, vector> // and so on
I couldn't find a way using templates, so I switched to macros. The
code below compiles on VC 7.1

// manager.h

#include <vector>
#include <list>

#define DECLARE_MANAGER_CLASS(Content, Namespace, Container) \
class manager_##Content##_Namespace##_##Container \
{ \
public: \
void add(Content value) \
{ \
m_container.push_back(value); \
} \
\
protected: \
Namespace::Container <Content> m_container; \
}

#define MANAGER_CLASS(Content, Namespace, Container) \
manager_##Content##_Namespace##_##Container

// we declare the classes we need
DECLARE_MANAGER_CLASS(int, std, vector);
DECLARE_MANAGER_CLASS(float, std, list);


// main.cpp

#include "manager.h"

int main()
{
MANAGER_CLASS(int, std, vector) x;
MANAGER_CLASS(float, std, list) y;

return 0;
}

I don't like the idea of maintaining identical parameter lists in two
places, but at least, if they are mismatched, you'll get a compilation
error.

dan
 
V

Victor Bazarov

Arne said:
I got a headache on this problem, maybe someone can help me here
I want to create a class which can be handled like this

manager<int, list> // possible variant
manager<int, vector> // another possible variant
manager<float, vector> // and so on

I cannot just create / pass a vector<int>. I need the first information
(e.g. int) inside the manager class, because I wrap this type inside
another template (see below)
The problem is - how do I define such a template? My first Idea was
"leave it to the compiler"

template <class tContent, class tContainer> class manager {

void add(anotherBase<tContent>);

protected:
tContainer<anotherBase<tContent> > m_container;
};

which does not work, because "tContainer is not a template".

So, what prevents you from declaring 'tContainer' a template?
So my question - is this possible at all? I did not find anything on
that topic in "The C++ Programming Language", and that's a IMHO a bad
sign ...
Maybe someone knows another way of doing such a thing (derivation would
be possible, but ugly in this case).


template<class tContent, template<class> tContainer> class manager {
....
};

Now, you won't be able to use 'vector' or 'list' directly because they
can have more than one template argument. You can, however, do a trick
with a special template template wrapper:

template<class T> struct use_vector { typedef std::vector<T> t; };
template<class T> struct use_list { typedef std::list<T> t; };

and now, when you declare your manager, do:

manager<int, use_vector::t> miv;
manager<double, use_list::t> mdl;

V
 
A

Arne Claus

template said:
So, what prevents you from declaring 'tContainer' a template?

template<class tContent, template<class> tContainer> class manager {

Ah - I already tried (which did not work)

template<class tContent, template<class T> tContainer<T>> class manager

but your attempt somehow makes more sense :)
Now, you won't be able to use 'vector' or 'list' directly because they
can have more than one template argument.

That's no problem, as I don't actually use vector or list but own
classes (wrappers on e.g. vectors) with exactly one parameter - so that
works fine. But nice to know what to do in such a case.

Thank you.
Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top