C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Can I pass a method name as a template parameter ?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Vesselin
Guest





PostPosted: Mon Oct 27, 2003 8:37 am    Post subject: Can I pass a method name as a template parameter ? Reply with quote



I need to pass a method name as a template parameter:

struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

struct bar{

template <class T>
int usefoo(foo const *f) const {
return f->T();
}

int do_bar() const {
foo f;


//How can the next line evaluate to (&f)->foo1() + (&f)->foo2() ?
return usefoo<foo1>(&f) + usefoo<foo2>(&f); //does not work Sad
}
}

I know I can do similar things with member function pointers but this
kills the inlining of foo methods.

Thanks in advance

Vesselin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ben Hutchings
Guest





PostPosted: Tue Oct 28, 2003 1:55 am    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote



In article <84b16e14.0310261840.49f95bde (AT) posting (DOT) google.com>,
Vesselin wrote:
Quote:
I need to pass a method name as a template parameter:

That can't be done.

Quote:
struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

struct bar{

template <class T
int usefoo(foo const *f) const {
return f->T();
}

int do_bar() const {
foo f;


//How can the next line evaluate to (&f)->foo1() + (&f)->foo2() ?
return usefoo<foo1>(&f) + usefoo<foo2>(&f); //does not work Sad
}
}

I know I can do similar things with member function pointers but this
kills the inlining of foo methods.

You can use a member function pointer as a template parameter. This
might work (in fact I know it works; I just don't know whether it
will run as fast as you want):

struct bar{
template <int (foo::*pmf)() const>
int usefoo(foo const *f) const {
return (f->*pmf)();
}

int do_bar() const {
foo f;
return usefoo<&foo::foo1>(&f) + usefoo<&foo::foo2>(&f);
}
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Richard Smith
Guest





PostPosted: Tue Oct 28, 2003 2:13 am    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote



Vesselin wrote:

Quote:
struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

[...]

Quote:
template <class T
int usefoo(foo const *f) const {
return f->T();
}

The syntax should be

template < int (foo::*Fn)(void) const >
int usefoo(foo const *f) const {
return (f->*Fn)();
}

Quote:
//How can the next line evaluate to (&f)->foo1() + (&f)->foo2() ?
return usefoo<foo1>(&f) + usefoo<foo2>(&f); //does not work Sad

And this line should read

return usefoo<&foo::foo1>(&f) + usefoo<&foo::foo2>(&f);

Quote:
I know I can do similar things with member function pointers but this
kills the inlining of foo methods.

With a good compiler, compile-time function pointers, such
as the ones above, will be inlined, even though run-time
ones probably wouldn't be.

--
Richard Smith

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
David Turner
Guest





PostPosted: Tue Oct 28, 2003 2:19 am    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote

Hi

Quote:

I know I can do similar things with member function pointers but this
kills the inlining of foo methods.


No it doesn't. Who told you that?

Regards
David Turner



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Richard Smith
Guest





PostPosted: Tue Oct 28, 2003 3:53 pm    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote

David Turner wrote:

Quote:
I know I can do similar things with member function pointers but this
kills the inlining of foo methods.

No it doesn't. Who told you that?

There are two different ways to use pointers to member
function in this context. One (run-time pointers) is very
likely to kill inlining (although if the call to usefoo()
is itself inlined right back to the literal pointer to
member function, inlining might still be possible):

int usefoo( foo const* f,
void (foo::*fn)(void) const ) const {
return (f->*fn)();
}

The other (compile-time pointers) will still be considered
for inlining by a good compiler:

template < void (foo::*Fn)(void) const >
int usefoo( foo const* f ) const {
return (f->*Fn)();
}

--
Richard Smith

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Derek Ledbetter
Guest





PostPosted: Tue Oct 28, 2003 6:35 pm    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote

On Mon, 27 Oct 2003 0:37:34 -0800, Vesselin wrote
(in message <84b16e14.0310261840.49f95bde (AT) posting (DOT) google.com>):

The template parameter has to be a pointer, not a type. Try this:

struct bar{
typedef int (foo::*FooMemberFuncType)() const;

template <FooMemberFuncType F>
int usefoo(foo const *f) const {
return (f->*F)();
}

int do_bar() const {
foo f;

return usefoo<&foo::foo1>(&f) + usefoo<&foo::foo2>(&f);
}
};

--
Derek Ledbetter
[email]derekledbetter (AT) attbi (DOT) com[/email]
"Life's short and hard like a body-building elf."


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Kevin Cline
Guest





PostPosted: Tue Oct 28, 2003 6:40 pm    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote

[email]vesselin (AT) beonic (DOT) com[/email] (Vesselin) wrote in message news:<84b16e14.0310261840.49f95bde (AT) posting (DOT) google.com>...
Quote:
I need to pass a method name as a template parameter:

struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

struct bar{

template <class T
int usefoo(foo const *f) const {
return f->T();
}

int do_bar() const {
foo f;


//How can the next line evaluate to (&f)->foo1() + (&f)->foo2() ?
return usefoo<foo1>(&f) + usefoo<foo2>(&f); //does not work Sad
}
}

I know I can do similar things with member function pointers but this
kills the inlining of foo methods.

You can't separate the member function name from the class name, but
you can say:

struct foo {
int x();
};

template <int (foo::*func)()>
int usefoo(const foo& f)
{
return (f.*func)();
}

static void h()
{
foo f;
g<foo:Mad>(f);
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ron
Guest





PostPosted: Tue Oct 28, 2003 6:43 pm    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote

Quote:
I need to pass a method name as a template parameter:

struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

struct bar{

template <class T
int usefoo(foo const *f) const {
return f->T();
}

int do_bar() const {
foo f;


//How can the next line evaluate to (&f)->foo1() + (&f)->foo2() ?
return usefoo<foo1>(&f) + usefoo<foo2>(&f); //does not work Sad
}
}

I know I can do similar things with member function pointers but this
kills the inlining of foo methods.

I'm not sure that the following, which uses member function pointers,
does kill inlining. The compiler knows, at template instantiation
time, which methods are to be called, so there's no theoretical
roadblock to inlining them.

-Ron

struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}

typedef int (foo::*fptr) () const ;
};

struct bar{

template <class T, typename T::fptr f>
int usefoo(T const &t) const {
return (t.*f)();
}

int do_bar() const {
foo f;
return usefoo<foo, &foo::foo1>(f) + usefoo<foo, &foo::foo2>(f);
}
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Vesselin
Guest





PostPosted: Wed Oct 29, 2003 4:41 pm    Post subject: Re: Can I pass a method name as a template parameter ? Reply with quote

I think I got it:

struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

struct foo_foo1 {
int operator() (const foo& f) {return f.foo1();}
};

struct foo_foo2 {
int operator() (const foo& f) {return f.foo2();}
};

struct bar{
int do_bar() const {
struct foo f;
return foo_foo1()(f) + foo_foo2()(f);
}
};

Not as good-looking as I hoped but should do the trick.

Thank you all for your replies!

Vesselin



Quote:
I need to pass a method name as a template parameter:

struct foo {
int foo1() const {return 1;}
int foo2() const {return 2;}
};

struct bar{

template <class T
int usefoo(foo const *f) const {
return f->T();
}

int do_bar() const {
foo f;

//How can the next line evaluate to (&f)->foo1() + (&f)->foo2() ?
return usefoo<foo1>(&f) + usefoo<foo2>(&f); //does not work Sad
}
}
.....


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.