STL map, compare function

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

    #1

    STL map, compare function

    Hi

    I have a requirement where I am declaring a map within a class.

    class abc {
    map <void*, void*mMap; // I do not pass compare struct here.
    ....
    };

    Here I am not passing compare function, but I want to do it into the
    constructor of class abc. Is it possible? Above void* could well be
    char* and in that case user will initialize it with some char compare
    function , but I don't know how to accomplish above task. Can I do
    something like

    abc::abc() : mMap(compare_st ring) {}

    But above dosen't work !!

    So I want to try something like function pointers, see the code below

    bool comp_default(co nst void *a, const void *b) { return a < b; }
    bool CharStringCompa re(const void* a, const void* b) {return
    strcmp((char*)a , (char*)b) < 0;}
    struct compare_key_ {
    bool operator()(cons t void* a, const void* b)
    {
    return (abc::*mComp)(a , b); // I know this is wrong as I am not
    using object here
    }
    };

    class abc {
    friend struct compare_key_;
    bool (abc::*mComp) (const void*, const void*) ;
    map<void*, void*, compare_key_mMa p;
    ....
    };

    But above code is not the correct thing I am doing, I just wanted to
    let you know the direction I am thinking? Can someone please help me
    out.

    Thanks
    S
  • Kai-Uwe Bux

    #2
    Re: STL map, compare function

    S S wrote:
    Hi
    >
    I have a requirement where I am declaring a map within a class.
    >
    class abc {
    map <void*, void*mMap; // I do not pass compare struct here.
    ...
    };
    >
    Here I am not passing compare function, but I want to do it into the
    constructor of class abc. Is it possible?
    No. You have to specify the type of the comparison object beforehand.
    Above void* could well be
    char* and in that case user will initialize it with some char compare
    function , but I don't know how to accomplish above task.
    Sounds like a bad idea. But anyway, you can use tr1::function, somewhat
    like so:

    typedef tr1::function< bool(void*,void *) void_ptr_compar e;
    map< void*, void*, void_ptr_compar e mMap;

    Now, you can initialize mMap from anything that can be used to compare
    void*.
    Can I do something like
    >
    abc::abc() : mMap(compare_st ring) {}
    >
    But above dosen't work !!
    Well, that would depend on many things (including the meaning of
    compare_string) .
    So I want to try something like function pointers, see the code below
    >
    bool comp_default(co nst void *a, const void *b) { return a < b; }
    bool CharStringCompa re(const void* a, const void* b) {return
    strcmp((char*)a , (char*)b) < 0;}
    struct compare_key_ {
    bool operator()(cons t void* a, const void* b)
    {
    return (abc::*mComp)(a , b); // I know this is wrong as I am not
    using object here
    }
    };
    Make the function pointer a member of compare_key_ and pass it upon
    construction of compare_key_.
    class abc {
    friend struct compare_key_;
    bool (abc::*mComp) (const void*, const void*) ;
    map<void*, void*, compare_key_mMa p;
    ...
    };
    >
    But above code is not the correct thing I am doing, I just wanted to
    let you know the direction I am thinking? Can someone please help me
    out.
    You seem to be headed the wrong direction. What is the underlying problem
    you are trying to solve. Very likely, the use of void* is already a mistake
    and right now you are about to compound it.


    Best

    Kai-Uwe Bux

    Comment

    • Juha Nieminen

      #3
      Re: STL map, compare function

      S S wrote:
      map <void*, void*mMap; // I do not pass compare struct here.
      In C++, if you feel the need to use void* (except when dealing with
      some C library), that's a good sign that you are doing something wrong.

      I have programmed C++ as a hobby and professionally for about 10
      years, and I have never needed to use "void*". (Well, I actually have a
      few times, but only when dealing with some C libraries which required
      them. That's an exception.)

      Anyways, std::map requires that you give the comparator type as
      template parameter if the default comparator doesn't suffice. There's no
      way around that.

      Comment

      • S S

        #4
        Re: STL map, compare function

        On Jun 23, 7:19 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
        S S wrote:
        Hi
        >
        I have a requirement where I am declaring a map within a class.
        >
        class abc {
        map <void*, void*mMap; // I do not pass compare struct here.
        ...
        };
        >
        Here I am not passing compare function, but I want to do it into the
        constructor of class abc. Is it possible?
        >
        No. You have to specify the type of the comparison object beforehand.
        If you look for STL map's function, it says a constructor like,
        map(const key_compare& k)
        Not sure what it is for..
        >
        Above void* could well be
        char* and in that case user will initialize it with some char compare
        function , but I don't know how to accomplish above task.
        >
        Sounds like a bad idea. But anyway,  you can use tr1::function, somewhat
        like so:
        >
          typedef tr1::function< bool(void*,void *) void_ptr_compar e;
          map< void*, void*, void_ptr_compar e mMap;
        >
        Now, you can initialize mMap from anything that can be used to compare
        void*.
        >
        Can I do something like
        >
        abc::abc() : mMap(compare_st ring) {}
        >
        But above dosen't work !!
        >
        Well, that would depend on many things (including the meaning of
        compare_string) .
        >
        So I want to try something like function pointers, see the code below
        >
        bool comp_default(co nst void *a, const void *b) { return  a < b; }
        bool CharStringCompa re(const void* a, const void* b) {return
        strcmp((char*)a , (char*)b) < 0;}
        struct compare_key_ {
           bool operator()(cons t void* a, const void* b)
           {
               return (abc::*mComp)(a , b); // I know this is wrong as Iam not
        using object here
           }
        };
        >
        Make the function pointer a member of compare_key_ and pass it upon
        construction of compare_key_.
        This wont help probably as I need to let mComp point differently
        depending on each 'abc' object.
        >
        class abc {
        friend struct compare_key_;
        bool (abc::*mComp) (const void*, const void*) ;
        map<void*, void*, compare_key_mMa p;
        ...
        };
        >
        But above code is not the correct thing I am doing, I just wanted to
        let you know the direction I am thinking? Can someone please help me
        out.
        >
        You seem to be headed the wrong direction. What is the underlying problem
        you are trying to solve. Very likely, the use of void* is already a mistake
        I am trying to create a HashTable class (a hash implementation) , here
        I am using void*, it can store pointers / integers / char* /
        anything....
        and right now you are about to compound it.
        >
        Best
        >
        Kai-Uwe Bux

        Comment

        • Kai-Uwe Bux

          #5
          Re: STL map, compare function

          S S wrote:
          On Jun 23, 7:19 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
          >S S wrote:
          Hi
          >>
          I have a requirement where I am declaring a map within a class.
          >>
          class abc {
          map <void*, void*mMap; // I do not pass compare struct here.
          ...
          };
          >>
          Here I am not passing compare function, but I want to do it into the
          constructor of class abc. Is it possible?
          >>
          >No. You have to specify the type of the comparison object beforehand.
          >
          If you look for STL map's function, it says a constructor like,
          map(const key_compare& k)
          Not sure what it is for..
          It is for creating a map that uses k as the comparison predicate for keys.
          However, that does not change the fact that the type key_compare has to be
          specified beforehand. The map template takes up to four type parameters.
          The third is the comparison predicate. So

          map< key_type, mapped_type, key_compare >

          is what you need. (The fourth argument would be the type for an allocator.)
          >>
          Above void* could well be
          char* and in that case user will initialize it with some char compare
          function , but I don't know how to accomplish above task.
          >>
          >Sounds like a bad idea. But anyway,  you can use tr1::function, somewhat
          >like so:
          >>
          >typedef tr1::function< bool(void*,void *) void_ptr_compar e;
          >map< void*, void*, void_ptr_compar e mMap;
          >>
          >Now, you can initialize mMap from anything that can be used to compare
          >void*.
          >>
          Can I do something like
          >>
          abc::abc() : mMap(compare_st ring) {}
          >>
          But above dosen't work !!
          >>
          >Well, that would depend on many things (including the meaning of
          >compare_string ).
          >>
          So I want to try something like function pointers, see the code below
          >>
          bool comp_default(co nst void *a, const void *b) { return  a < b; }
          bool CharStringCompa re(const void* a, const void* b) {return
          strcmp((char*)a , (char*)b) < 0;}
          struct compare_key_ {
          bool operator()(cons t void* a, const void* b)
          {
          return (abc::*mComp)(a , b); // I know this is wrong as I am not
          using object here
          }
          };
          >>
          >Make the function pointer a member of compare_key_ and pass it upon
          >construction of compare_key_.
          >
          This wont help probably as I need to let mComp point differently
          depending on each 'abc' object.
          And your point is? So, abc looks like so:

          class abc {

          map< void*, void*, compare_key_ mMap;

          public:

          abc ( ..., bool(*compariso n_ptr)(void*,vo id*) )
          : mMap( compare_key_( comparison_ptr ) )
          {}

          ...

          };

          However, tr1::function is more flexible than compare_key_ anyway.

          class abc {
          friend struct compare_key_;
          bool (abc::*mComp) (const void*, const void*) ;
          map<void*, void*, compare_key_mMa p;
          ...
          };
          >>
          But above code is not the correct thing I am doing, I just wanted to
          let you know the direction I am thinking? Can someone please help me
          out.
          >>
          >You seem to be headed the wrong direction. What is the underlying problem
          >you are trying to solve. Very likely, the use of void* is already a
          >mistake
          >
          I am trying to create a HashTable class (a hash implementation) , here
          I am using void*, it can store pointers / integers / char* /
          anything....
          No need for void*. Make your hash table a template.

          template < typename KeyType, typename MappedType, typename HashFct >
          class hash_table {
          public:

          hash_table( HashFct const & f = HashFct() );

          void insert( KeyType const & key, MappedType const & value );#

          ...

          };

          It is to be used as follows:

          hash_table< int, int, IntHash >


          One could even go on and provide a default for HastFct that has
          specializations for built-in types and other bells and whistles.



          BTW: you could just use the hash table from the upcoming standard.
          tr1::unordered_ map might be more or less what you are looking for.




          Best

          Kai-Uwe Bux

          Comment

          • James Kanze

            #6
            Re: STL map, compare function

            On Jun 23, 3:27 pm, S S <sarvesh.si...@ gmail.comwrote:
            I have a requirement where I am declaring a map within a class.
            class abc {
            map <void*, void*mMap; // I do not pass compare struct here.
            ...
            };
            Here I am not passing compare function, but I want to do it
            into the constructor of class abc.
            There are two issues: the type of the comparator, and its
            "value". The type becomes part of the type of the map, and must
            be specified when you declare the map. (The map itself holds an
            instance of this type, so the compiler must know its size.) The
            value can be specified when you initialize the object, in this
            case, in the initializer list of abc::abc. (It cannot be
            changed later, except with swap, for obvious reasons.)

            By default, the *type* of the comparator is std::less<Key>.
            Since all instances of this class have the same behavior,
            there's never any point of setting it to a particular value in
            the constructor, but this is not necessarily true for other
            comparators. If you declare:

            map< void*, void*, bool (*)( void*, void* ) mMap ;

            for example, you almost certainly want to pass an actual
            instance of the comparator to the constructor. (The default
            value here is a null pointer, which isn't going to work too
            well.)
            Is it possible? Above void* could well be char* and in that
            case user will initialize it with some char compare function ,
            but I don't know how to accomplish above task. Can I do
            something like
            abc::abc() : mMap(compare_st ring) {}
            But above dosen't work !!
            It does if you declare mMap so that it takes a comparator of
            type compare_string. (Or if compare_string has the type
            std::less< key_type >, but of course, there's no point in it in
            that case.)
            So I want to try something like function pointers, see the
            code below
            bool comp_default(co nst void *a, const void *b) { return a < b; }
            bool CharStringCompa re(const void* a, const void* b) {return
            strcmp((char*)a , (char*)b) < 0;}
            struct compare_key_ {
            bool operator()(cons t void* a, const void* b)
            {
            return (abc::*mComp)(a , b); // I know this is wrong as I am not
            using object here
            }
            };
            You don't need the structure.
            class abc {
            friend struct compare_key_;
            bool (abc::*mComp) (const void*, const void*) ;
            map<void*, void*, compare_key_mMa p;
            Why not
            std::map< void*, void*, bool (*)( void const*, void const* ) >
            mMap ;
            initialized with:

            abc::abc()
            : mMap( &CharStringComp are )
            ...
            ...
            };
            But above code is not the correct thing I am doing, I just
            wanted to let you know the direction I am thinking? Can
            someone please help me out.
            Well, I'm very suspicious of your use of void* to begin with,
            and I think you probably have to think about const correctness a
            bit more as well. But there's no problem of having a comparator
            which does something different depending on its state; a pointer
            to function, for example (which will do something different
            depending on which function it points to).

            --
            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

            Working...