stl and standard library functions

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

    stl and standard library functions

    I am somewhat new to STL and the plethora of library functions they have. I
    looked at sgi's stl info. and I was overwhelmed so I thought I would present
    my question here.

    I have
    std::map<WWN*, Drive*> m_Drives

    I want to take that and run a functor through all of them (the functor has
    Drive* has the parameter type) and whichever ones meet the predicate functor
    will need to be added to a list of Drive*s. (std::list<Driv e*> driveList)

    I can write a loop to do this and in fact, I will do it here to show what I
    am trying to achieve. But I would rather use the library functions, if
    possible.

    for ( mapIter i = m_Drives.begin( ); i != m_Drives.end(); ++i )
    {
    if ( i.second->getType == someType && i.second->getCapacity >=
    someCapacity )
    driveList.push_ back(i.second);
    }

    My code may not compile since I just wrote it on the fly.
    My for loop is only few lines long so maybe doing that is better than using
    the standard library functions.

    However, I read part of Scott Meyers's Effective STL stuff and he says that
    standard functions are efficient, correct, and maintainable. Anyway, any
    help would be nice.

    Thanks.


  • Julián Albo

    #2
    Re: stl and standard library functions

    sks_cpp escribió:
    [color=blue]
    > I have
    > std::map<WWN*, Drive*> m_Drives
    >
    > I want to take that and run a functor through all of them (the functor has
    > Drive* has the parameter type) and whichever ones meet the predicate functor
    > will need to be added to a list of Drive*s. (std::list<Driv e*> driveList)
    >
    > I can write a loop to do this and in fact, I will do it here to show what I
    > am trying to achieve. But I would rather use the library functions, if
    > possible.
    >
    > for ( mapIter i = m_Drives.begin( ); i != m_Drives.end(); ++i )
    > {
    > if ( i.second->getType == someType && i.second->getCapacity >=
    > someCapacity )
    > driveList.push_ back(i.second);
    > }[/color]

    Something like that (untested):

    class SelectDrive {
    public:
    SelectDrive (std::list <Drive *> & driveList, Type type, int capacity)
    :
    driveList (driveList), type (type), capacity (capacity)
    { }
    void operator () (const std::map <WWN *, Drive *>::value_type & i)
    {
    if (i.second->getType == someType && i.second->getCapacity >=
    capacity)
    driveList.push_ back (i.second);
    }
    private:
    std::list <Drive *> & driveList;
    Type type;
    int capacity;
    };

    An use as:

    std::for_each (m_Drives.begin (), m_Drives.end (),
    SelectDrive (driveList, someType, someCapacity) );

    Regards.

    Comment

    • Jerry Coffin

      #3
      Re: stl and standard library functions

      In article <BSiLa.338099$3 n5.329748@news2 .central.cox.ne t>,
      sksjava@hotmail .com says...[color=blue]
      > I am somewhat new to STL and the plethora of library functions they have. I
      > looked at sgi's stl info. and I was overwhelmed so I thought I would present
      > my question here.
      >
      > I have
      > std::map<WWN*, Drive*> m_Drives
      >
      > I want to take that and run a functor through all of them (the functor has
      > Drive* has the parameter type) and whichever ones meet the predicate functor
      > will need to be added to a list of Drive*s. (std::list<Driv e*> driveList)[/color]

      std::remove_cop y_if seems to be what you're looking for. Using this
      you'll have to reverse the sense of your predicate -- it copies
      elements, removing those for which the predicate is true, rather than
      only copying those for which it is true.

      // warning: untested code.
      bool your_predicate( std::pair<WWN*, Drive *> p) {
      return (p.second->getType != someType ||
      p.second->getCapacity < someCapacity);
      }

      std::remove_cop y_if(m_drives.b egin(), m_drives.end(),
      std::inserter(d riveList, driveList.end() ),
      your_predicate) ;

      Please don't ask me why the committee preferred remove_copy_if to
      copy_if -- I have no idea, and mostly disagree. At least to me, the
      name std::remove_cop y_if sounds like it should be a variant of
      std::unique, or something on that order, but it's basically just the
      (unfortunately nonexistent) std::copy_if having a really bad hair day.

      --
      Later,
      Jerry.

      The universe is a figment of its own imagination.

      Comment

      • sks_cpp

        #4
        Re: stl and standard library functions

        "Jerry Coffin" <jcoffin@taeus. com> wrote in message
        news:MPG.1968c2 f97158b664989a9 5@news.clspco.a delphia.net...
        [color=blue]
        > std::remove_cop y_if(m_drives.b egin(), m_drives.end(),
        > std::inserter(d riveList, driveList.end() ),
        > your_predicate) ;[/color]

        I don't want to remove from the map - just insert the ones that meet the
        criteria into the list. Is that what the above code does? What does inserter
        do?
        [color=blue]
        > Please don't ask me why the committee preferred remove_copy_if to
        > copy_if -- I have no idea, and mostly disagree. At least to me, the
        > name std::remove_cop y_if sounds like it should be a variant of
        > std::unique, or something on that order, but it's basically just the
        > (unfortunately nonexistent) std::copy_if having a really bad hair day.[/color]

        I might have to agree with you here.

        Thanks for your suggestions/comments.


        Comment

        • sks_cpp

          #5
          Re: stl and standard library functions

          "Julián Albo" <JULIANALBO@ter ra.es> wrote in message
          news:3EFDBF0B.F 141A471@terra.e s...[color=blue]
          > class SelectDrive {
          > public:
          > SelectDrive (std::list <Drive *> & driveList, Type type, int capacity)
          > :
          > driveList (driveList), type (type), capacity (capacity)
          > { }
          > void operator () (const std::map <WWN *, Drive *>::value_type & i)
          > {
          > if (i.second->getType == someType && i.second->getCapacity >=
          > capacity)
          > driveList.push_ back (i.second);
          > }
          > private:
          > std::list <Drive *> & driveList;
          > Type type;
          > int capacity;
          > };[/color]

          Thanks for your coments. I found something interesting with your operator
          method. It takes "value_type " as its parameter. Now, could it have taken a
          pair? What if you overload the operators with ambiguous parameters, such as
          "value_type " as you have it and "pair<WWN*, Drive*>" - is that a compiler
          error or does one have precedence over the other?

          Thanks.



          Comment

          • Jerry Coffin

            #6
            Re: stl and standard library functions

            In article <qlILa.345190$3 n5.159755@news2 .central.cox.ne t>,
            sksjava@hotmail .com says...[color=blue]
            > "Jerry Coffin" <jcoffin@taeus. com> wrote in message
            > news:MPG.1968c2 f97158b664989a9 5@news.clspco.a delphia.net...
            >[color=green]
            > > std::remove_cop y_if(m_drives.b egin(), m_drives.end(),
            > > std::inserter(d riveList, driveList.end() ),
            > > your_predicate) ;[/color]
            >
            > I don't want to remove from the map - just insert the ones that meet the
            > criteria into the list.[/color]

            That's part of what I meant about remove_copy_if having a deceiving
            name. It leaves the contents of the original container unaffected. It
            just removes the items from the copy -- which is to say that if they
            meet the criteria, it doesn't copy them.
            [color=blue]
            > Is that what the above code does? What does inserter do?[/color]

            Yes. std::inserter is just a utility function that creates an
            insert_iterator for a particular spot in a particular container. In
            case you're not familiar with insert_iterator s (and
            back_insert_ite rators, etc.) they're iterators that insert items into a
            collection -- i.e. they don't just overwrite items at locations, but
            create space for new ones. e.g. with something like this:

            std::vector x, y;

            for(int i=0; i<10; ++i)
            x.push_back(i);

            std::copy(x.beg in(), x.end(), back_inserter(y , y.end());

            the back_inserter creates an iterator that basically does a push_back to
            put each item into y. This saves you from having to resize y to the
            correct size ahead of time, which would be trivial in the situation
            above, but much more difficult in a situation like yours, where you
            don't know ahead of time how many items you'll be inserting into the
            list.

            --
            Later,
            Jerry.

            The universe is a figment of its own imagination.

            Comment

            • Jerry Coffin

              #7
              Re: stl and standard library functions

              In article <MPG.196957f6d1 66f39e989a96@ne ws.clspco.adelp hia.net>,
              jcoffin@taeus.c om says...

              [ ... ]
              [color=blue]
              > std::copy(x.beg in(), x.end(), back_inserter(y , y.end());[/color]

              Oops -- with back_inserter, you don't need to specify an iterator, since
              it always inserts at the back. I.e. the call above should be just:

              std::copy(x.beg in(), x.end(), back_inserter(y ));

              with std::inserter, you have to specify an iterator as the point where
              the insertion(s) will take place, since (unlike back_inserter) it's not
              implicit.

              --
              Later,
              Jerry.

              The universe is a figment of its own imagination.

              Comment

              Working...