| View previous topic :: View next topic |
| Author |
Message |
Vesselin Guest
|
Posted: Mon Oct 27, 2003 8:37 am Post subject: Can I pass a method name as a template parameter ? |
|
|
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
}
}
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
|
Posted: Tue Oct 28, 2003 1:55 am Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
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
}
}
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
|
Posted: Tue Oct 28, 2003 2:13 am Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
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
|
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
|
Posted: Tue Oct 28, 2003 2:19 am Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
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
|
Posted: Tue Oct 28, 2003 3:53 pm Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
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
|
Posted: Tue Oct 28, 2003 6:35 pm Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
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
|
Posted: Tue Oct 28, 2003 6:40 pm Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
[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
}
}
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: >(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
|
Posted: Tue Oct 28, 2003 6:43 pm Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
| 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
}
}
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
|
Posted: Wed Oct 29, 2003 4:41 pm Post subject: Re: Can I pass a method name as a template parameter ? |
|
|
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
}
}
..... |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|