CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Feb 2002
    Posts
    5,757

    Debuggin a Simple STL Algorithm :: STL

    Hi.

    I would like to debug a simple algorithm that does not work using an STL solution. The solution works via iteration.

    std::list<unsigned int> theList;

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

    // theList should now contain 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9.

    // Remove "6" from the list.
    // Assume that iTheList is an iterator that points to element with value 6.

    theList.erase(iTheList);

    // After erase() theList should now contain 0, 1, 2, 3, 4, 5, 7, 8, and 9.

    Okay. Everything above works as designed. Now I would like to decrement everything bigger or equal to "6," thus make theList hold 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. Here is the iterative solution.

    Code:
    // Given iTheList points to theList.begin().
    
    while (*iTheList <= 6)
    ++iTheList
    
    // Now decrement until end of theList.
    
    while (*iTheList != theList.end()
    {
       *iTheList = *iTheList - 1;
       ++iTheList;
    }
    The iterative solution above works perfect.

    I would like to implement a more efficient and elegant solution. Here is one solution using STL algorithms. However, it does not work correctly.

    Code:
    std::for_each(std::find_if(theList.begin(), theList.end(), std::bind2nd(std::greater<>, 6)), theList.end(), std::bind2nd(std::minus<>, 1));
    The STL solution above does not work. The logic and syntec seem to be valid.

    Is there a logic or syntec misunderstanding in the STL solution? I looked over the function objects and function adapter. They are valid.

    Thanks,
    KUphryn

  2. #2
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    I think your problem is in instantiating the greater and minus functions (I'll split the code because I think it reads better that way):
    Code:
    std::list<unsigned int>:: iterator i = 
            std::find_if(theList.begin(), theList.end(), std::bind2nd(std::greater<unsigned int>(), 6));
    
    std::for_each(i, theList.end(), std::bind2nd(std::minus<unsigned int>(), 1));
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  3. #3
    Join Date
    Feb 2002
    Posts
    5,757
    Okay. Thanks.

    Fruny posted a solution at GameDev using transform().

    http://www.gamedev.net/community/for...opic_id=120974

    In general, what is the problem of my original STL solution?

    Kuphryn

  4. #4
    Join Date
    Feb 2002
    Posts
    5,757
    Okay. I added a class object that will do the minus manually.

    Code:
    template <typename T>
    class DecreaseOne : public std::binary_function<T, T, void>
    {
       public:
          void operator()(T &lp, const T &rp)
          {
             lp -= rp;
          }
    };
    [/code]

    Here the call to it.

    Code:
    std::for_each(std::find_if(theList.begin(), theList.end(), std::bind2nd(std::greater<size_t>(), 6)), theList.end(), std::bind2nd(DecreaseOne<size_t>(), 1));
    The compiler will not compile. Here is the errors.

    Code:
    error C2064: term does not evaluate to a function
    error C2662: 'DecreaseOne<unsigned int>::operator`()'' : cannot convert 'this' pointer from 'const DecreaseOne<T>' to 'DecreaseOne<T> &'
            with
            [
                T=size_t
            ]
            and
            [
                T=size_t
            ]
    I defined DecreaseOne functor as a global class.

    What is the problem?

    Thanks,
    Kuphryn

  5. #5
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    std::for_each is classed as a non-mutating algorithm, meaning it's not allowed to change the value that the iterator points to. The other poster was correct to suggest std::transform, which is a mutating algorithm.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  6. #6
    Join Date
    Feb 2002
    Posts
    5,757
    ahhhhh. Okay. Thanks.

    Kuphryn

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured