external functionality with a functor object?

Discussion in 'C++' started by aaragon, Sep 22, 2006.

  1. aaragon

    aaragon Guest

    Hi everyone,

    I'm trying to provide some external functionality to a class through a
    functor object defined by the user. The concept is as follows:

    template <class Functor>
    class ClassA
    {
    ...
    double evaluate(){
    Functor functor_;
    return functor_();
    }
    ...
    };

    // defined by the uesr
    struct Functor
    {
    double operator() (){
    return 2+2;
    }
    };

    int main(int argc, char *argv[])
    {
    ClassA<Functor> a;
    a.evaluate();
    }

    The problem that I have is that the functor needs to know what the
    ClassA is to work. So I thought that maybe using a templatized functor
    may work:
    template <class T>
    struct Functor
    {
    double operator() (T t_){
    return t_.x() + t_.y();
    }
    };
    This was a good idea except for the fact that now I have no idea of how
    the user is going to delacre an object of classA =/
    Any ideas????
    aaragon, Sep 22, 2006
    #1
    1. Advertising

  2. aaragon wrote:
    > I'm trying to provide some external functionality to a class through a
    > functor object defined by the user. The concept is as follows:
    >
    > template <class Functor>
    > class ClassA
    > {
    > ...
    > double evaluate(){
    > Functor functor_;
    > return functor_();


    Or, in one line instead of two:

    return Functor()();

    :)

    > }
    > ...
    > };
    >
    > // defined by the uesr
    > struct Functor
    > {
    > double operator() (){
    > return 2+2;
    > }
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > ClassA<Functor> a;
    > a.evaluate();
    > }
    >
    > The problem that I have is that the functor needs to know what the
    > ClassA is to work. So I thought that maybe using a templatized
    > functor may work:
    > template <class T>
    > struct Functor
    > {
    > double operator() (T t_){
    > return t_.x() + t_.y();
    > }


    How about making your 'operator()' a template?

    struct Functor
    {
    template<class T> double operator()(T t_) {
    return t_.x() + t_.y();
    }
    };

    > };
    > This was a good idea except for the fact that now I have no idea of
    > how the user is going to delacre an object of classA =/
    > Any ideas????


    See above.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 22, 2006
    #2
    1. Advertising

  3. aaragon

    Guest

    aaragon wrote:
    > Hi everyone,
    >
    > I'm trying to provide some external functionality to a class through a
    > functor object defined by the user. The concept is as follows:
    >
    > template <class Functor>
    > class ClassA
    > {
    > ...
    > double evaluate(){
    > Functor functor_;
    > return functor_();
    > }
    > ...
    > };
    >
    > // defined by the uesr
    > struct Functor
    > {
    > double operator() (){
    > return 2+2;
    > }
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > ClassA<Functor> a;
    > a.evaluate();
    > }
    >
    > The problem that I have is that the functor needs to know what the
    > ClassA is to work. So I thought that maybe using a templatized functor
    > may work:
    > template <class T>
    > struct Functor
    > {
    > double operator() (T t_){
    > return t_.x() + t_.y();
    > }
    > };
    > This was a good idea except for the fact that now I have no idea of how
    > the user is going to delacre an object of classA =/
    > Any ideas????


    Not sure what you are trying to do by that Template Functor but this
    should work.

    struct eval
    {
    int x(){
    return 1;
    }
    int y(){
    return 2;
    }

    };

    template <class Functor>
    class ClassA
    {
    public:
    eval tmp;
    double evaluate(){
    Functor functor_;
    return functor_(tmp);
    }
    };


    template <class T>
    struct Functor
    {
    double operator() (T t_){
    return t_.x() + t_.y();
    }

    };

    int main(int argc, char* argv[])
    {

    ClassA<Functor<eval> > a;
    a.evaluate();
    }
    , Sep 22, 2006
    #3
  4. aaragon

    aaragon Guest

    Victor Bazarov wrote:
    > aaragon wrote:
    > > I'm trying to provide some external functionality to a class through a
    > > functor object defined by the user. The concept is as follows:
    > >
    > > template <class Functor>
    > > class ClassA
    > > {
    > > ...
    > > double evaluate(){
    > > Functor functor_;
    > > return functor_();

    >
    > Or, in one line instead of two:
    >
    > return Functor()();
    >
    > :)
    >
    > > }
    > > ...
    > > };
    > >
    > > // defined by the uesr
    > > struct Functor
    > > {
    > > double operator() (){
    > > return 2+2;
    > > }
    > > };
    > >
    > > int main(int argc, char *argv[])
    > > {
    > > ClassA<Functor> a;
    > > a.evaluate();
    > > }
    > >
    > > The problem that I have is that the functor needs to know what the
    > > ClassA is to work. So I thought that maybe using a templatized
    > > functor may work:
    > > template <class T>
    > > struct Functor
    > > {
    > > double operator() (T t_){
    > > return t_.x() + t_.y();
    > > }

    >
    > How about making your 'operator()' a template?
    >
    > struct Functor
    > {
    > template<class T> double operator()(T t_) {
    > return t_.x() + t_.y();
    > }
    > };
    >


    Yes! This works fine! =)

    > > };
    > > This was a good idea except for the fact that now I have no idea of
    > > how the user is going to delacre an object of classA =/
    > > Any ideas????

    >
    > See above.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    However, I still have one problem. The user needs to implement the
    entire functor and I don't think that is nice. Maybe if I write a
    hidden implementation of the functor and the let the user only to
    override the function ()(), perhaps???
    aaragon, Sep 22, 2006
    #4
  5. aaragon wrote:
    > [..]
    > However, I still have one problem. The user needs to implement the
    > entire functor and I don't think that is nice. Maybe if I write a
    > hidden implementation of the functor and the let the user only to
    > override the function ()(), perhaps???


    I don't understand the problem. Can you elaborate?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 22, 2006
    #5
  6. aaragon

    aaragon Guest

    Victor Bazarov wrote:
    > aaragon wrote:
    > > [..]
    > > However, I still have one problem. The user needs to implement the
    > > entire functor and I don't think that is nice. Maybe if I write a
    > > hidden implementation of the functor and the let the user only to
    > > override the function ()(), perhaps???

    >
    > I don't understand the problem. Can you elaborate?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    Sure. Well, the way you mentioned works just fine. But the idea is to
    hide the implementation details for the user. Let's say, the user has
    to write:

    struct Functor
    {
    template<class T>
    double operator()(T t_) {
    return t_.x() + t_.y();
    }
    };

    int main(int argc, char *argv[])
    {
    ClassA<Functor> a;
    a.evaluate();
    ....
    }

    and for someone who does not have idea about C++, the functor struct is
    just hard! So, I was thinking that it may be a good idea to do
    something easier, like overriding the function because the user does
    not have to deal with implementation details. If the user does not put
    template<class T> the functor will not work. Any ideas to accomplish
    this?
    aaragon, Sep 22, 2006
    #6
  7. aaragon wrote:

    > I'm trying to provide some external functionality to a class through a
    > functor object defined by the user. The concept is as follows:
    >
    > template <class Functor>
    > class ClassA
    > {
    > ...
    > double evaluate(){
    > Functor functor_;
    > return functor_();
    > }
    > ...
    > };
    >
    > // defined by the uesr
    > struct Functor
    > {
    > double operator() (){
    > return 2+2;
    > }
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > ClassA<Functor> a;
    > a.evaluate();
    > }


    Did you need all this templates? A simpler way can be:

    class ClassA {
    public:
    // ...
    virtual double operator () ()= 0;
    //...
    double evaluate ()
    {
    return operator () ();
    }
    };


    class UserClassA : public ClassA {
    double operator () ()
    {
    return 2 + 2;
    }
    };

    int main ()
    {
    UserClassA a;
    a.evaluate ();
    }

    --
    Salu2
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Sep 22, 2006
    #7
  8. aaragon wrote:
    > Victor Bazarov wrote:
    >> aaragon wrote:
    >>> [..]
    >>> However, I still have one problem. The user needs to implement the
    >>> entire functor and I don't think that is nice. Maybe if I write a
    >>> hidden implementation of the functor and the let the user only to
    >>> override the function ()(), perhaps???

    >>
    >> I don't understand the problem. Can you elaborate?
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    > Sure. Well, the way you mentioned works just fine. But the idea is
    > to hide the implementation details for the user. Let's say, the user
    > has to write:
    >
    > struct Functor
    > {
    > template<class T>
    > double operator()(T t_) {
    > return t_.x() + t_.y();
    > }
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > ClassA<Functor> a;
    > a.evaluate();
    > ...
    > }
    >
    > and for someone who does not have idea about C++, the functor struct
    > is just hard! So, I was thinking that it may be a good idea to do
    > something easier, like overriding the function because the user does
    > not have to deal with implementation details. If the user does not
    > put template<class T> the functor will not work. Any ideas to
    > accomplish this?


    So, what is the user supposed to write to accomplish what they need?
    If the 'Functor' above is hard (and yes, member templates are not the
    simplest thing to understand, I give you that), what would be "easy"
    for somebody "who does not have idea about C++"? If they don't have
    a clue, why would they be writing those functors?

    Let's suppose you want to make their life easier. You write some kind
    of base class

    class BaseFunctor { /* not sure what goes here yet */ };

    , right? OK, how the user will make use of it? They would have to
    know to derive from it, correct? So

    class UserFunctor : public Functor { /* something */ };

    and then to achieve the goal they would need to know how to override
    a virtual function and not to change the signature... It seems that
    they still would need to know a lot.

    Of course, another approach is to hide the scary template stuff into
    a macro, like this:

    #define FUNCTOR_METHOD(type, arg) \
    template<class T> double operator()(T arg)

    and then ask your user to do

    struct Functor {
    FUNCTOR_METHOD(double, t_) {
    return t_.x() + t_.y();
    }
    };

    Is that better?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 23, 2006
    #8
  9. aaragon

    aaragon Guest

    Victor Bazarov wrote:
    > aaragon wrote:
    > > Victor Bazarov wrote:
    > >> aaragon wrote:
    > >>> [..]
    > >>> However, I still have one problem. The user needs to implement the
    > >>> entire functor and I don't think that is nice. Maybe if I write a
    > >>> hidden implementation of the functor and the let the user only to
    > >>> override the function ()(), perhaps???
    > >>
    > >> I don't understand the problem. Can you elaborate?
    > >>
    > >> V
    > >> --
    > >> Please remove capital 'A's when replying by e-mail
    > >> I do not respond to top-posted replies, please don't ask

    > >
    > > Sure. Well, the way you mentioned works just fine. But the idea is
    > > to hide the implementation details for the user. Let's say, the user
    > > has to write:
    > >
    > > struct Functor
    > > {
    > > template<class T>
    > > double operator()(T t_) {
    > > return t_.x() + t_.y();
    > > }
    > > };
    > >
    > > int main(int argc, char *argv[])
    > > {
    > > ClassA<Functor> a;
    > > a.evaluate();
    > > ...
    > > }
    > >
    > > and for someone who does not have idea about C++, the functor struct
    > > is just hard! So, I was thinking that it may be a good idea to do
    > > something easier, like overriding the function because the user does
    > > not have to deal with implementation details. If the user does not
    > > put template<class T> the functor will not work. Any ideas to
    > > accomplish this?

    >
    > So, what is the user supposed to write to accomplish what they need?
    > If the 'Functor' above is hard (and yes, member templates are not the
    > simplest thing to understand, I give you that), what would be "easy"
    > for somebody "who does not have idea about C++"? If they don't have
    > a clue, why would they be writing those functors?
    >
    > Let's suppose you want to make their life easier. You write some kind
    > of base class
    >
    > class BaseFunctor { /* not sure what goes here yet */ };
    >
    > , right? OK, how the user will make use of it? They would have to
    > know to derive from it, correct? So
    >
    > class UserFunctor : public Functor { /* something */ };
    >
    > and then to achieve the goal they would need to know how to override
    > a virtual function and not to change the signature... It seems that
    > they still would need to know a lot.
    >
    > Of course, another approach is to hide the scary template stuff into
    > a macro, like this:
    >
    > #define FUNCTOR_METHOD(type, arg) \
    > template<class T> double operator()(T arg)
    >
    > and then ask your user to do
    >
    > struct Functor {
    > FUNCTOR_METHOD(double, t_) {
    > return t_.x() + t_.y();
    > }
    > };
    >
    > Is that better?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    =) That's a good idea! (altough I don't like to deal with macros for
    some reason). Another would be to pass just a function instead of an
    object, right? Maybe that's also an easy way to implement this. What
    do you think?
    aaragon, Sep 23, 2006
    #9
  10. aaragon wrote:
    > Victor Bazarov wrote:
    >> [..]
    >> Of course, another approach is to hide the scary template stuff into
    >> a macro, like this:
    >>
    >> #define FUNCTOR_METHOD(type, arg) \
    >> template<class T> double operator()(T arg)
    >>
    >> and then ask your user to do
    >>
    >> struct Functor {
    >> FUNCTOR_METHOD(double, t_) {
    >> return t_.x() + t_.y();
    >> }
    >> };
    >>
    >> Is that better?
    >>
    >> V
    >> --
    >> Please remove capital 'A's when replying by e-mail
    >> I do not respond to top-posted replies, please don't ask

    >
    > =) That's a good idea! (altough I don't like to deal with macros for
    > some reason). Another would be to pass just a function instead of an
    > object, right? Maybe that's also an easy way to implement this. What
    > do you think?


    Yes, functions are essentially functors (in C++ terms) since when named
    by their name they can be called using the function call operator.

    You still haven't explained how your users that aren't very sophisticated
    (by your own opinion) will deal with those things. What do you expect
    them to be able to do? What level do you think they need to be at to be
    able to use your library? I am not saying you should require them to
    implement type traits with a bunch of typedefs and static members to
    successfully utilize your library, but FCOL, if they don't know C++ (or
    most of it), maybe you should concentrate on Visual Basic mechanism for
    them to use?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 24, 2006
    #10
  11. aaragon

    aaragon Guest

    Victor Bazarov wrote:
    > aaragon wrote:
    > > Victor Bazarov wrote:
    > >> [..]
    > >> Of course, another approach is to hide the scary template stuff into
    > >> a macro, like this:
    > >>
    > >> #define FUNCTOR_METHOD(type, arg) \
    > >> template<class T> double operator()(T arg)
    > >>
    > >> and then ask your user to do
    > >>
    > >> struct Functor {
    > >> FUNCTOR_METHOD(double, t_) {
    > >> return t_.x() + t_.y();
    > >> }
    > >> };
    > >>
    > >> Is that better?
    > >>
    > >> V
    > >> --
    > >> Please remove capital 'A's when replying by e-mail
    > >> I do not respond to top-posted replies, please don't ask

    > >
    > > =) That's a good idea! (altough I don't like to deal with macros for
    > > some reason). Another would be to pass just a function instead of an
    > > object, right? Maybe that's also an easy way to implement this. What
    > > do you think?

    >
    > Yes, functions are essentially functors (in C++ terms) since when named
    > by their name they can be called using the function call operator.
    >
    > You still haven't explained how your users that aren't very sophisticated
    > (by your own opinion) will deal with those things. What do you expect
    > them to be able to do? What level do you think they need to be at to be
    > able to use your library? I am not saying you should require them to
    > implement type traits with a bunch of typedefs and static members to
    > successfully utilize your library, but FCOL, if they don't know C++ (or
    > most of it), maybe you should concentrate on Visual Basic mechanism for
    > them to use?
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    Well, I was expecting the users to write functions only so they don't
    have to mess with writing a class or struct to provide the functor
    object. I guess that the option of using the macro is the closest to
    what I'm expecting. It shouldn't be encouraging to have a library that
    is not user-friendly.
    aaragon, Sep 25, 2006
    #11
  12. aaragon wrote:
    > [..]
    > Well, I was expecting the users to write functions only so they don't
    > have to mess with writing a class or struct to provide the functor
    > object.


    Then you shouldn't ask them to use your class. You should ask them to
    use a function (which would actually be a function template, in which
    the type of the argument would be deduced from a call...)

    You've given this example:

    struct Functor
    {
    template<class T>
    double operator()(T t_) {
    return t_.x() + t_.y();
    }
    };

    int main(int argc, char *argv[])
    {
    ClassA<Functor> a;
    a.evaluate();
    ...
    }

    My question would be, does 'a' get used after "a.evaluate()" in 'main'?
    If yes, how? If not, why not? See, 'ClassA' is *your* class, but the
    code is supposedly written by the user, correct? Perhaps you should
    find a different way, like

    double Function(ClassA const& a)
    {
    return a.x() + a.y();
    }

    int main()
    {
    ClassA a;
    a.evaluate(Functor);
    ...
    }

    where 'evaluate' would be a template that applies its argument to
    'this' object:

    class ClassA {
    ...
    template<class F> void evaluate(F f)
    {
    double d = f(*this);
    }
    };

    .. In this case the user only has to write a function.

    > I guess that the option of using the macro is the closest to
    > what I'm expecting. It shouldn't be encouraging to have a library
    > that is not user-friendly.


    <sigh> I think nowadays some folks confuse "user-friendly" with
    "moron-oriented".

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 25, 2006
    #12
  13. aaragon

    aaragon Guest

    Victor Bazarov wrote:
    > aaragon wrote:
    > > [..]
    > > Well, I was expecting the users to write functions only so they don't
    > > have to mess with writing a class or struct to provide the functor
    > > object.

    >
    > Then you shouldn't ask them to use your class. You should ask them to
    > use a function (which would actually be a function template, in which
    > the type of the argument would be deduced from a call...)
    >
    > You've given this example:
    >
    > struct Functor
    > {
    > template<class T>
    > double operator()(T t_) {
    > return t_.x() + t_.y();
    > }
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > ClassA<Functor> a;
    > a.evaluate();
    > ...
    > }
    >
    > My question would be, does 'a' get used after "a.evaluate()" in 'main'?
    > If yes, how? If not, why not? See, 'ClassA' is *your* class, but the
    > code is supposedly written by the user, correct? Perhaps you should
    > find a different way, like
    >
    > double Function(ClassA const& a)
    > {
    > return a.x() + a.y();
    > }
    >
    > int main()
    > {
    > ClassA a;
    > a.evaluate(Functor);
    > ...
    > }
    >
    > where 'evaluate' would be a template that applies its argument to
    > 'this' object:
    >
    > class ClassA {
    > ...
    > template<class F> void evaluate(F f)
    > {
    > double d = f(*this);
    > }
    > };
    >
    > . In this case the user only has to write a function.
    >
    > > I guess that the option of using the macro is the closest to
    > > what I'm expecting. It shouldn't be encouraging to have a library
    > > that is not user-friendly.

    >
    > <sigh> I think nowadays some folks confuse "user-friendly" with
    > "moron-oriented".
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    Well, the idea behind the actual code is much more complicated than
    what I wrote in these messages. I just put a simplified version of
    what I want to do. The actual code consists in about 5 classes and
    each one is within the next one. GA class, which has a population
    class, wich has many individual classes which have a chromosome class.
    So the idea is that each chromosome has to be evaluated with an
    external function that is provided by the user and this evaluation is
    passed to the GA class so that evolution can take place in the next
    generation. So, the actual functor is not used again in the main.cpp
    code but within the actual library.

    I was able to solve the problem of evaluating chromosomes with by
    passing the functor object when the chromosome template is
    instantiated.

    Regarding the "moron-oriented" statement. Well, I guess you're right
    about that. It's just that the C++ knowledge of most people who use
    libraries does not go beyond writing functions. I'll consider to see
    if I can write the objective function as a function instead of as a
    functor (even though I don't know yet how to do this, because this is
    also new for me).

    aaragon, Sep 25, 2006
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. davout
    Replies:
    0
    Views:
    398
    davout
    Oct 25, 2003
  2. Chandra Shekhar Kumar

    functor object in template class

    Chandra Shekhar Kumar, Jun 24, 2003, in forum: C++
    Replies:
    5
    Views:
    1,269
    porschberg
    Jun 26, 2003
  3. CoolPint
    Replies:
    3
    Views:
    708
    tom_usenet
    Dec 29, 2003
  4. Charles-Antoine Giuliani

    Multiple operator() overloading for functor object

    Charles-Antoine Giuliani, Sep 20, 2004, in forum: C++
    Replies:
    2
    Views:
    1,137
    Charles-Antoine Giuliani
    Sep 20, 2004
  5. mthread
    Replies:
    4
    Views:
    456
    James Kanze
    Jun 1, 2009
Loading...

Share This Page