Templates functions as template parameters

T

tygro

Hi,
I would like to do something like this:

class Type
{
public:

template <template<typename> class Fun>
void applyOnType(Fun f, void* data)
{
switch(type) {
case 0:
f<int>(data);
break;
case 1:
f<short>(data);
break;
}
};

Then I could call:
template <typename T> void myFunction(T* data) { }

DataType dt;
dt.applyOnType(myFunction, data);


But it doesn't work because I guess it is not possible to pass a
template function in argument to a function.
Furthermore, because of the template-template, it seems that Fun must be
functor.
Do you see a way to write something as flexible as this but which could
compile?

My only working solution was this:
class TypeFunc
{
public:
template<typename T> void operator()() {}
};

void onDataType(TypeFunc& f, void* data)
{
switch(..) {
...
f.operator()<int>();
...
}
}

I don't think it's easy to use. I also have a macro based solution, but
I would prefer something 100% template.

Thank you for your help.
 
V

Victor Bazarov

tygro said:
Hi,
I would like to do something like this:

class Type
{
public:

template <template<typename> class Fun>
void applyOnType(Fun f, void* data)
{
switch(type) {

What's "type"? It's not defined here.
case 0:
f<int>(data);
break;
case 1:
f<short>(data);
break;
}
};

Then I could call:
template <typename T> void myFunction(T* data) { }

DataType dt;
dt.applyOnType(myFunction, data);


But it doesn't work because I guess it is not possible to pass a
template function in argument to a function.
Furthermore, because of the template-template, it seems that Fun must
be functor.

A function is a functor. No big deal.
Do you see a way to write something as flexible as this but which
could compile?

Flexible? Looks like too flexible.
My only working solution was this:
class TypeFunc
{
public:
template<typename T> void operator()() {}
};

void onDataType(TypeFunc& f, void* data)
{
switch(..) {
...
f.operator()<int>();
...
}
}

I don't think it's easy to use. I also have a macro based solution, but I
would prefer something 100% template.

Try looking in the FAQ first. Then if you have some questions
remainging unanswered, come back and ask again. Start with 5.8,
then move onto section 35 (templates).

Also, perhaps you could explain what you're trying to accomplish
with design like yours.

V
 
T

tygro

Thank you for the quick response.

Victor said:
A function is a functor. No big deal.
So maybe I'm doing something bad. Can you explain this:
template <typename T>
class testFunctor
{
public:
void operator()() {}
};

template <typename T> void purFunction() {}

template <template<typename> class Fun>
void dummy()
{
Fun<int>();
}

int main()
{
dummy<testFunctor>();
dummy<purFunction>();

return 0
}

Flexible? Looks like too flexible.
Not really.
Try looking in the FAQ first. Then if you have some questions
remainging unanswered, come back and ask again. Start with 5.8,
then move onto section 35 (templates).
I have already looked at the FAQ and a lot of books.
Also, perhaps you could explain what you're trying to accomplish
with design like yours.
I have a void* and a type as an enum. There is nothing to do against
this fact.
So I want to be able to write template functions which will be instanced
according to type.
 
V

Victor Bazarov

tygro said:
Thank you for the quick response.


So maybe I'm doing something bad. Can you explain this:
template <typename T>
class testFunctor
{
public:
void operator()() {}
};

template <typename T> void purFunction() {}

template <template<typename> class Fun>
^^^^^
Here's your "culprit". You said you'll be passing a template
of a class (i.e. a class template). A function template is
not a class template.
void dummy()
{
Fun<int>();
}

int main()
{
dummy<testFunctor>();
dummy<purFunction>();

return 0
}

dummy<purFunction>() won't compile.

You need to look at the 'std::tr1::function'. I am not sure how to
use it, but I bet you that's where you'll find what you're looking for.

V
 
J

John Gilson

Hi,
I would like to do something like this:

class Type
{
public:

template <template<typename> class Fun>
void applyOnType(Fun f, void* data)
{
switch(type) {
case 0:
f<int>(data);
break;
case 1:
f<short>(data);
break;
}

};

Then I could call:
template <typename T> void myFunction(T* data) { }

DataType dt;
dt.applyOnType(myFunction, data);

But it doesn't work because I guess it is not possible to pass a
template function in argument to a function.
Furthermore, because of the template-template, it seems that Fun must be
functor.
Do you see a way to write something as flexible as this but which could
compile?

My only working solution was this:
class TypeFunc
{
public:
template<typename T> void operator()() {}

};

void onDataType(TypeFunc& f, void* data)
{
switch(..) {
...
f.operator()<int>();
...
}

}

I don't think it's easy to use. I also have a macro based solution, but
I would prefer something 100% template.

Thank you for your help.

You're on the right track. You can't pass a function template as an
argument (a function template is a template but not a function) but
you can pass an object whose type is a class that has defined an
appropriate member function template:

template <typename T> void myFunction(T * data);

class TypeFunc
{
public:
template<typename T> void operator()(T * data) const
{
myFunction(data);
}
};

class Type
{
public:
template<typename F>
void applyOnType(const F & f, void * data)
{
switch(type) // Assume "type" is defined in scope
{
case 0:
f(static_cast<int *>(data));
break;
case 1:
f(static_cast<short *>(data));
break;
// ...
}
}
};

Type t;
void * data = ...;
t.applyOnType(TypeFunc(), data);

-- JAG
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top