0

This is the code I have made, however, what is being displayed is incorrect. Kindly teach me what do I need to fix.

#include <iostream>
#include <list>
using namespace std;

bool check(int passing){
    int g;
    if(g<=passing){
        return false;
    }else{
        return true;
    }
}

int main()
{
    int pg;

    cout<<"What is the passing grade?"<<endl;
    cin>>pg;

    list<int> grades = {100,90,93,95,92,98,97,99,96,94};
    grades.remove_if(check);
    for(int x : grades){
        cout<<x<<'\t';
    }
    return 0;
}
trese
  • 15
  • 5
  • 3
    Explain what `int g; if(g<=passing)` is intended to do, especially considering `g` has no determinate value prior to comparing it to `passing` . Methinks `g` should be a formal parameter, not a local var, and it should be receiving `pg` from `main` as its argument, bound by either lambda or a std bind. In fact, get rid of `check` entirely and just implement as a lambda down in `main`. – WhozCraig Jan 23 '22 at 13:08
  • int g; if(g<=passing) will be used to determine the grades on the list. g corresponds to the list on main(). what should i do? – trese Jan 23 '22 at 13:13
  • [DEMO](https://onlinegdb.com/QKHjy6euK). Either you use lambda to pass the `passing grade` to `check` function – TruthSeeker Jan 23 '22 at 13:14
  • how do you use lambda – trese Jan 23 '22 at 13:17

2 Answers2

0

Here you are:

#include <iostream>
#include <list>
#include <functional>

bool check(int const lhs, int const rhs) {
    return lhs < rhs;
}

int main() {
    int pg;
    std::cout << "What is the passing grade?\n";
    std::cin >> pg;
    std::list<int> grades{
        70, 90, 79, 85, 96, 73, 99, 91, 81, 83,
        99, 94, 80, 79, 85, 83, 82, 90, 84, 82,
        72, 83, 76, 93, 90, 77, 82, 76, 100, 94
    };
    grades.remove_if(std::bind(check, std::placeholders::_1, pg));
    for (auto const g : grades) {
        std::cout << g << '\t';
    }
    return 0;
}

The function check has to return true when asked whether to remove the particular element which it was called with. Since remove_if requires unary predicate (function that can be called with 1 argument only) I used std::bind to generate new callable which when called passes the arguments std::placeholders::_1 and pg to check where instead of std::placeholders::_1 a copy of an element from grades is used.

Let's play this with pg = 90.

check(70, 90) -> Is 70 < 90 ? -> yes -> remove

check(90, 90) -> Is 90 < 90 ? -> no -> keep

check(79, 90) -> Is 79 < 90 ? -> yes -> remove

check(85, 90) -> Is 85 < 90 ? -> yes -> remove

check(96, 90) -> Is 96 < 90 ? -> no -> keep

I think you got the point.

  • thanks. i get it. but is there a simpler way to do this without using std::bind ?? – trese Jan 23 '22 at 13:42
  • There are two more namely lambda and struct/class that has operator() overloaded and can be called as a function but actually when you use the first one (lambda) the compiler transforms it into the second one (struct/class that has operator() overloaded). –  Jan 23 '22 at 13:44
0

Use a lambda as a predicate for remove_if like below:

#include <iostream>
#include <list>


int main( )
{
    std::cout << "What is the passing grade?\n";
    int passingGrade { };
    std::cin >> passingGrade;

    std::list<int> grades { 100, 90, 93, 95, 92, 49, 50, 98, 97, 99, 11, 94 };

    /*grades.remove_if( [ &passingGrade ]( const int grade ) // lambda approach
                      {
                          return ( grade < passingGrade ) ? true : false;
                      }
                    );*/

    for ( auto it = grades.begin( ); it != grades.end( ); ) // for-loop approach
    {
        if ( *it < passingGrade )
        {
            it = grades.erase( it );
        }
        else
        {
            ++it;
        }
    }

    for ( const int grade : grades )
    {
        std::cout << grade << '\t';
    }
}

Sample I/O

What is the passing grade?
50
100     90      93      95      92      50      98      97      99      94

Another sample:

What is the passing grade?
95
100     95      98      97      99
digito_evo
  • 3,216
  • 2
  • 14
  • 42