Function object, this and constructor

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • vulpes

    Function object, this and constructor

    This similar situation will explain somewhat, what I want to do:

    class X {
    public:
    X() : map_(*this) {}

    bool operator() (int a, int b) { return goodStuff(a) <
    goodStuff(b); }
    int goodStuff(int a) { ... }

    private:
    map<int, int, Xmap_;
    };

    Why do I want this? Because the goodStuff function is already there
    and I don't want to write it twice. This piece of code doesn't work as
    one would expect. I also tried doing things like

    class X {
    public:
    X() : map_( ptr_fun(&X::stu ff) ) {}

    bool stuff(int a, int b) const { return goodStuff(a) <
    goodStuff(b); }

    private:
    map< int, int, binary_function <int, int, bool map_;
    };

    but this works neither. Is there a way to do this thing. The X objects
    are a pain to construct (lots of big stuff in 'em) so I don't want to
    generate them anymore than I have to. I guess that second could be
    made to work if the goodStuff would be static, but it ain't.

    This isn't a stopper problem, I know a way around this (problem-
    specific), but it stinks. I want to know how to do this "the way it
    should be done".

  • anon

    #2
    Re: Function object, this and constructor

    vulpes wrote:
    This similar situation will explain somewhat, what I want to do:
    >
    class X {
    public:
    X() : map_(*this) {}
    >
    bool operator() (int a, int b) { return goodStuff(a) <
    goodStuff(b); }
    int goodStuff(int a) { ... }
    >
    private:
    map<int, int, Xmap_;
    };
    So you construct the map<int,intvari able from the X class.
    Take a look here what are map constructors expecting:

    >
    Why do I want this? Because the goodStuff function is already there
    and I don't want to write it twice. This piece of code doesn't work as
    one would expect. I also tried doing things like
    >
    class X {
    public:
    X() : map_( ptr_fun(&X::stu ff) ) {}
    >
    bool stuff(int a, int b) const { return goodStuff(a) <
    goodStuff(b); }
    >
    private:
    map< int, int, binary_function <int, int, bool map_;
    };
    What is ptr_fun?
    Here is the same as the previous. You want to construct the map<int,int>
    object from ptr_fun (whatever that is)

    >
    but this works neither. Is there a way to do this thing. The X objects
    are a pain to construct (lots of big stuff in 'em) so I don't want to
    generate them anymore than I have to. I guess that second could be
    made to work if the goodStuff would be static, but it ain't.
    >
    This isn't a stopper problem, I know a way around this (problem-
    specific), but it stinks. I want to know how to do this "the way it
    should be done".
    >
    You message was not clear enough for me to understand what exactly you
    want to do.
    Why your solution stinks?

    Comment

    • James Kanze

      #3
      Re: Function object, this and constructor

      On Jul 9, 1:11 am, vulpes <ntv...@luukku. comwrote:
      This similar situation will explain somewhat, what I want to do:
      class X {
      public:
      X() : map_(*this) {}
      bool operator() (int a, int b) { return goodStuff(a) <
      goodStuff(b); }
      int goodStuff(int a) { ... }
      private:
      map<int, int, Xmap_;
      };
      Why do I want this? Because the goodStuff function is already there
      and I don't want to write it twice. This piece of code doesn't work as
      one would expect.
      What would one expect? It's undefined behavior. (I expect that
      it will not compile with most implementations . I can't think of
      any reasonable implementation of map where the class itself
      doesn't contain an instance of the comparator. So what you've
      written is that X contains a map which contains an X...)
      I also tried doing things like
      class X {
      public:
      X() : map_( ptr_fun(&X::stu ff) ) {}
      bool stuff(int a, int b) const { return goodStuff(a) <
      goodStuff(b); }
      private:
      map< int, int, binary_function <int, int, bool map_;
      };
      but this works neither. Is there a way to do this thing.
      The obvious (but not necessarily good) solution is to replace
      the map with a pointer to the map. Alternatively, just about
      any form of indirection in the comparator should work:

      class X ;
      class XCmp
      {
      public:
      XCmp( X const* owner ) ;
      bool operator()( int, int ) const ;

      private:
      X const* myOwner ;
      } ;

      class X
      {
      // ...
      private:
      std::map< int, int, XCmp >
      myMap ;
      } ;
      The X objects
      are a pain to construct (lots of big stuff in 'em) so I don't want to
      generate them anymore than I have to.
      Then you almost certainly don't want to use one directly as
      comparator. The actual map uses a *copy* of the object it is
      passed in the constructor (or a default constructed instance, if
      it isn't passed a comparator).
      I guess that second could be
      made to work if the goodStuff would be static, but it ain't.
      You could probably work out something using boost::bind. The
      basic problem is that you have a function with three arguments
      (the X and the two ints), and map will want to call it with two,
      so you need to use a functional object which contains a pointer
      to (or a reference to) the X. And you can't do it with the
      standard binders, because the (current) version of the standard
      doesn't support functional objects with more than two
      parameters.
      This isn't a stopper problem, I know a way around this
      (problem- specific), but it stinks. I want to know how to do
      this "the way it should be done".
      "The way it should be done" probably depends on the context, but
      most likely involves a comparator object with a pointer to (or a
      reference to) the owning X.

      --
      James Kanze (GABI Software) email:james.kan ze@gmail.com
      Conseils en informatique orientée objet/
      Beratung in objektorientier ter Datenverarbeitu ng
      9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

      Comment

      • anon

        #4
        Re: Function object, this and constructor

        vulpes wrote:
        This similar situation will explain somewhat, what I want to do:
        >
        class X {
        public:
        X() : map_(*this) {}
        >
        bool operator() (int a, int b) { return goodStuff(a) <
        goodStuff(b); }
        int goodStuff(int a) { ... }
        >
        private:
        map<int, int, Xmap_;
        };
        #include <map>
        using namespace std;

        class X {
        public:
        X(){}

        bool operator() (int a, int b) { return goodStuff(a) <
        goodStuff(b); }
        int goodStuff(int a) { return a; }
        };

        class Y
        {
        public:
        Y():map_(x){}


        private:
        map<int, int, Xmap_;
        X x;
        };

        int main()
        {
        Y x;
        }

        Is this good enough for your use?

        Comment

        • vulpes

          #5
          Re: Function object, this and constructor

          On Jul 9, 1:06 pm, anon <a...@no.nowrot e:
          class X {
          public:
          X(){}
          >
          bool operator() (int a, int b) { return goodStuff(a) <
          goodStuff(b); }
          int goodStuff(int a) { return a; }
          };
          >
          class Y
          {
          public:
          Y() : map_(x){}
          >
          private:
          map<int, int, Xmap_;
          X x;
          };
          >
          int main()
          {
          Y x;
          }
          >
          Is this good enough for your use?
          Well it's fine otherwise, but I'd rather let the class X be the main
          character in the plot. Here's why: The class X is actually one of
          several concretizations to an interface class and I use the class X
          exclusively through that interface. It would be an unnecessary
          complication to create a whole facade in front of X. Therefore I
          wouldn't use your solution, it's like an inverse Adapter. But at least
          there seems to be a slew of ways to do it, if you just keep pressing
          the issue.

          Thanks for your help. If you want, I'll post my final decision and
          code here when I get to it (This evening European time I'd wager).
          Someone may benefit from it later on.

          Comment

          • BobR

            #6
            Re: Function object, this and constructor


            anon <anon@no.nowrot e in message...
            >
            What is ptr_fun?
            Here is the same as the previous. You want to construct the map<int,int>
            object from ptr_fun (whatever that is)
            >
            [ from STL docs ]

            - Description -
            Ptr_fun takes a function pointer as its argument and returns a function
            pointer adaptor, a type of function object. It is actually two different
            functions, not one (that is, the name ptr_fun is overloaded). If its
            argument is of type Result (*)(Arg) then ptr_fun creates a
            pointer_to_unar y_function, and if its argument is of type Result (*)(Arg1,
            Arg2) then ptr_fun creates a pointer_to_bina ry_function.

            - Definition -
            Defined in the standard header <functional>, and in the nonstandard
            backward-compatibility header <function.h>.

            --
            Bob R
            POVrookie


            Comment

            Working...