Jump to content
  • Advertisement
Sign in to follow this  
Timkin

pointer to function with template arguments?

This topic is 5425 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Unfortunately I can't seem to find any useful information on how to do this, or if it's even possible, hence I'm asking for help in here. Imagine a template function looking like:
template <typename T> int func(T arg1, int arg2);
First up... is this a legitimate way of defining a pointer to said template function?
template <typename T> int (*pfunc)(T arg1, int arg2);
Would this require an explicit instantiation to permit compilation? Second, how would you define this pointer to function in a typedef? Would it be:
typedef int(template <typename T> *pfoo)(T, int, int);
or something else? Maybe there's a better way to acheive what I want to do and the above might not then be relevant. I have a template function of the form above... that is,
template <typename T> int (*pfunc)(T arg1, int arg2);
and I have two other functions with nearly identical signatures: foo_type<V> func1(foo_type<V> arg1,int arg2,int (*pfunc)(foo_type<V>,int)); foo_type<V> func2(foo_type<V> arg1,int arg2,int (*pfunc)(foo_type<V>,int)); The algorithms implemented in func1 and func2 differ significantly... except that each calls pfunc, passing its first argument through to pfunc. The instantiations of pfunc depend on the type passed. Now, all of these function calls are occuring inside the constructor of a template class that has foo_type<V> as its template parameter. foo_type<V> is essentially the data type manipulated by the class. The user should be able to choose between func1 and func2, so I was thinking of storing a pointer to functions with the signature of func1 and func2 as an attribute of the class and change its value depending on what the user chooses. Furthermore, pfunc is being passed as a pointer because I want the other programmers to be able to supply their own function that fits that function signature. Thus, maybe pfunc should also be stored in a pointer to function within the class!? Is there a better way of doing this (but I'm not going to implement lots of switch statements based on input parameters). Any help is appreciated. Thanks, Timkin

Share this post


Link to post
Share on other sites
Advertisement
There is an easy way out and it comes bundled with OO design. Use some polymorphic behaviour wrapped up in a small class like so:


template <class _Ret, class _P1, class _P2>
struct functor_base
{
virtual _Ret operator()(_P1 _p1, _P2 _p2) = 0;
};


You then simply subclass this and provide an object derived from this type as your parameter. In your case your two functions.

The proto's for your two functions will then look something like this:


foo_type<V> func1(foo_type<V> arg1,int arg2,functor_base<int, foo_type<V>,int> &func);
foo_type<V> func2(foo_type<V> arg1,int arg2,functor_base<int, foo_type<V>,int> &func);


edit: oops...now that I think of it, boost has something like this too that might suit you better:D

Hope that helps!

Share this post


Link to post
Share on other sites
Quote:
Original post by Timkin
Unfortunately I can't seem to find any useful information on how to do this, or if it's even possible, hence I'm asking for help in here.

Imagine a template function looking like:

template <typename T> int func(T arg1, int arg2);


First up... is this a legitimate way of defining a pointer to said template function?

template <typename T> int (*pfunc)(T arg1, int arg2);



Not that i know of no.

I think there is a better way and it will make your code abit more flexiable & inlineable (with functors that is) [smile], doesn't involve pointers to functions directly, you can pass functions, member functions (need an instance of wright type to work with them), and functors. Just add another type to the template parameter list. e.g.


template < typename T, typename FunkyFunc >
inline foo_type<T> func(const foo_type<T>& f,int arg, FunkyFunc function) { /*...*/ }


Just give FunkyFunc argument a free function/member function/class function/functor.

you may need to change it a little for this to work with member functions because you need an instance of the same type as the member function belongs to.

[Edited by - snk_kid on September 8, 2004 1:23:28 AM]

Share this post


Link to post
Share on other sites
simplified illustrative example of technique previously described:


#include <iostream>

template < typename T, typename Func >
void foo(const T& f, Func function) {

function(f);

}

void print(const int& f) {

std::cout << "print1: " << f << '\n';

}

void print2(const int& f) {
std::cout << "print2: " << f << '\n';
}

void print3(const int& f) {
std::cout << "print3: " << f << '\n';
}

struct printer {

void operator()(const int& i) const {
std::cout << "Printer Functor: " << i << '\n';
}

};

int main() {


foo(45, print);

foo(54, print2);

foo(32, print3);

foo(99, printer());

return 0;

}


Share this post


Link to post
Share on other sites
I'm doing a little reading on functors and that aspect is starting to come together (slowly), but...

Quote:
Original post by snk_kid

template < typename T, typename FunkyFunc >
inline foo_type<T> func(const foo_type<T>& f,int arg, FunkyFunc function) { /*...*/ }


I have multiple functions with the above signature. How do I define a pointer to such functions as an attribute of some template class that takes T as its parameter. Furthermore, placing FunkyFunc in the parameter list forces it to be a compile time decision. What if I want to make it a run time decision... I can't then use the template parameter list to define types...


I'm working on an implementation at the moment based on what you have both said... I'll see how it goes... but if anyone can come up with a neat way of making the choices between func1 and func2 and the choice of function passed to either of these a runtime decision, I would appreciate being able to compare your solution to the one I'm working on. If I get mine to compile and run, I'll post it here.

Thanks,

Timkin

Share this post


Link to post
Share on other sites
Quote:
Original post by Timkin
I have multiple functions with the above signature.


if you mean overloaded functions, then you can do full/partial specializations to do something different on a paritcular types.

Quote:
Original post by Timkin
How do I define a pointer to such functions as an attribute of some template class that takes T as its parameter.


you mean something like this:


template < typename T >
class foo {
public:

typedef void (*bar_ptr)(const T&, const T&);

private:

bar_ptr f;

public:

foo(bar_ptr func): f(func) {}

void operator()(const T& a, const T& b) const {
(*f)(a, b);
}

};


but why would you need to do that?

if your doing what Krysole suggested its not really a functor but more of a generalized function but also known as a functor!!! if you need this then boost has re-usable generalized functions.

Quote:
Original post by Timkin
Furthermore, placing FunkyFunc in the parameter list forces it to be a compile time decision. What if I want to make it a run time decision... I can't then use the template parameter list to define types...


Why would you need to, did you have alook at my last post? for function that calls another function/functor i don't see how you could change it to point to another function at run-time that easily, also if you need to change to run-time feature you could always do an explicit template instantation that makes the function template parameter a pointer to function.

Quote:
Original post by Timkin
I'm working on an implementation at the moment based on what you have both said... I'll see how it goes... but if anyone can come up with a neat way of making the choices between func1 and func2 and the choice of function passed to either of these a runtime decision, I would appreciate being able to compare your solution to the one I'm working on. If I get mine to compile and run, I'll post it here.


maybe boost function is the way to go.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid

template < typename T >
class foo {...};


but why would you need to do that?


To hide all of this within the class that uses it and to privide a syntatically simple class interface that idiot programmers (some of the people I know will be using this library!) can handle.

Quote:
Original post by snk_kid
If you need this then boost has re-usable generalized functions.


I want to avoid 3rd party libraries if I can... but if, in the end, its the best way to go, I might go with Boost. I'll certainly take a look at it.

Quote:
Original post by snk_kid
Why would you need to, did you have alook at my last post?


Sorry, no. You posted it while I was writing my last post. I've since read your second post.

To those recommending Boost. Thanks. I'll take a look.

On the issue of typedef templates... I finally figured out the right keywords to find THIS page. Very interesting!

Share this post


Link to post
Share on other sites
i've messed with that for some time...and finally wrote that:

template<class T> struct damn{
void (*MyDamnInvocator)(void* , T);
};
damn<int> ti;
ti.MyDamnInvocator = &(MyInvocator< MyMode , int, &MyMode::Test >) ;
ti.MyDamnInvocator(static_cast<void*>(&m),7);

where

MyInvocator< MyMode , int, &MyMode::Test >(void*, T) is a damn templated function.

if you want you can overload operators () in "damn" to make it look better.

some kind of programmers tends to blindly assume that if something done like complete crap in C++ , it's not needed at all,because it's must be left for compatibility. In fact, C++ have very crappy support for pointers to functions,pointers to members (any other language have delegates instead,that also simpler to implement!), and many other little things.

edit: and boost is worse than third-party lib. As for functors, it's just set of third-party workarounds.

Share this post


Link to post
Share on other sites
Look at how Boost and Loki implement functors. Once you get the concept down it turns into a generative programming exercise more than anything else.

That being said, I prefer the Boost function syntax over Loki's use of type lists. However, Boost's function header slows my build tremendously. You may want to roll your own in this case.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!