[function] using with CRTP

Hi, This is probably a novice template question. I am curious what I am doing wrong here, where I'm trying to get a function object holding a base member of a CRTP class. gcc 4.2.3 complains about: type/value mismatch at argument 1 in template parameter list for 'template<class Derived> template<template<template<class> class MHBase> template<class Derived> template<class> class MHBase> struct MHBase< <template-parameter-1-1> >::fooFO Any help appreciated! Thanks, Russell #include <boost/function.hpp> #include <iostream> class MHBAccessor { template<class> friend class MHBase; template<class Derived> static int foo(Derived& derived, int i) { return derived.foo_(i); } }; typedef boost::function<int (int)> FooFunc; template <class Derived> struct MHBase { Derived& derived() { return static_cast<Derived&>(*this); } int foo(int i) { return MHBAccessor::foo(this->derived(), i); } template <template <class> class MHBase > struct fooFO { fooFO(MHBase<Derived>& mhb) : mhb_(mhb) {} void operator()(int i) { mhb_.foo(i); } private: MHBase<Derived>& mhb_; }; FooFunc getFooFunc() { FooFunc ff = fooFO<MHBase<Derived> >(*this); return ff; } }; class Put : public MHBase<Put> { friend class MHBAccessor; int foo_(int i) { return i; } }; int main(int argc, char **argv) { Put put; std::cout << put.foo(123) << std::endl; FooFunc ff = put.getFooFunc(); std::cout << ff(456) << std::endl; return 0; }

On Wednesday 23 January 2008 15:01:46 Russell L. Carter wrote:
Hi, This is probably a novice template question. I am curious what I am doing wrong here, where I'm trying to get a function object holding a base member of a CRTP class. gcc 4.2.3 complains about:
type/value mismatch at argument 1 in template parameter list for 'template<class Derived> template<template<template<class> class MHBase> template<class Derived> template<class> class MHBase> struct MHBase< <template-parameter-1-1> >::fooFO
I dont understand what you want to achieve so I can't recommend something based on that but strictly speaking about the issue, fooFO receives a template template parameter and not a type so you cannot give it an instantiation of MHBase, you probably want to give it MHBase. So: FooFunc ff = fooFO<MHBase>(*this); (even tho I don't understand why in that case fooFO is made to receive a template template parameter being defined inside MHBase, you do not need the flexibility of being able to give it something else than MHBase do you?) -- Mihai RUSU Email: dizzy@roedu.net "Linux is obsolete" -- AST

dizzy wrote:
I dont understand what you want to achieve so I can't recommend something based on that but strictly speaking about the issue, fooFO receives a template template parameter and not a type so you cannot give it an instantiation of MHBase, you probably want to give it MHBase. So:
FooFunc ff = fooFO<MHBase>(*this);
(even tho I don't understand why in that case fooFO is made to receive a template template parameter being defined inside MHBase, you do not need the flexibility of being able to give it something else than MHBase do you?)
Hi Dizzy, What I'm trying to do is generically package up a function object to the MHBase's member foo(). I can certainly do this directly for every derived class's member foo_() but I thought I would try to see if it could be done once in the MHBase. How do people accomplish this? Looking at it again with your comment in mind, the fooFO doesn't need to be a template (I think) so can be even more simplified, but then I get "void value not ignored as it ought to be" at the line: "FooFunc ff = put.getFooFunc();" I get the same thing if I try: FooFunc ff = MHBase<Put>::fooFO(put); Here's the code: #include <boost/function.hpp> #include <iostream> class MHBAccessor { template<class> friend class MHBase; template<class Derived> static int foo(Derived& derived, int i) { return derived.foo_(i); } }; typedef boost::function<int (int)> FooFunc; template <class Derived> struct MHBase { Derived& derived() { return static_cast<Derived&>(*this); } int foo(int i) { return MHBAccessor::foo(this->derived(), i); } struct fooFO { fooFO(MHBase<Derived>& mhb) : mhb_(mhb) {} void operator()(int i) { mhb_.foo(i); } private: MHBase<Derived>& mhb_; }; FooFunc getFooFunc() { FooFunc ff = fooFO(*this); return ff; } }; struct Put : public MHBase<Put> { private: friend class MHBAccessor; int foo_(int i) { return i; } }; int main(int argc, char **argv) { Put put; std::cout << put.foo(123) << std::endl; FooFunc ff = put.getFooFunc(); // FooFunc ff = MHBase<Put>::fooFO(put); std::cout << ff(456) << std::endl; return 0; }

AMDG Russell L. Carter wrote:
then I get "void value not ignored as it ought to be" at the line: "FooFunc ff = put.getFooFunc();"
I get the same thing if I try: FooFunc ff = MHBase<Put>::fooFO(put);
Here's the code:
#include <boost/function.hpp> #include <iostream>
class MHBAccessor { template<class> friend class MHBase; template<class Derived> static int foo(Derived& derived, int i) { return derived.foo_(i); } }; typedef boost::function<int (int)> FooFunc;
template <class Derived> struct MHBase { Derived& derived() { return static_cast<Derived&>(*this); }
int foo(int i) { return MHBAccessor::foo(this->derived(), i); }
struct fooFO { fooFO(MHBase<Derived>& mhb) : mhb_(mhb) {} void operator()(int i) { mhb_.foo(i); }
This returns void. FooFunc expects int. try int operator()(int i) { return(mhb_.foo(i)); } In Christ, Steven Watanabe

Doh! Thanks. Steven Watanabe wrote:
AMDG
Russell L. Carter wrote:
then I get "void value not ignored as it ought to be" at the line: "FooFunc ff = put.getFooFunc();"
I get the same thing if I try: FooFunc ff = MHBase<Put>::fooFO(put);
Here's the code:
#include <boost/function.hpp> #include <iostream>
class MHBAccessor { template<class> friend class MHBase; template<class Derived> static int foo(Derived& derived, int i) { return derived.foo_(i); } }; typedef boost::function<int (int)> FooFunc;
template <class Derived> struct MHBase { Derived& derived() { return static_cast<Derived&>(*this); }
int foo(int i) { return MHBAccessor::foo(this->derived(), i); }
struct fooFO { fooFO(MHBase<Derived>& mhb) : mhb_(mhb) {} void operator()(int i) { mhb_.foo(i); }
This returns void. FooFunc expects int. try
int operator()(int i) { return(mhb_.foo(i)); }
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
dizzy
-
Nat Goodspeed
-
Russell L. Carter
-
Steven Watanabe