use std::for_each with bind a member function on a std::set , the code can't be compile

I can compile normal,when I use vector:

TEST(function_obj,bindMemeber1){

    std::vector<Person> v {234,234,1241,1241,213,124,152,421};
    std::for_each(v.begin(),v.end(), std::bind(&Person::print,std::placeholders::_1) );
}

but when I use set,something wrong:

TEST(function_obj,bindMemeber1){
    std::set<Person,PersonCriterion> v{234,234,1241,1241,213,124,152,421};
    std::for_each(v.begin(),v.end(), std::bind(&Person::print,std::placeholders::_1) );
}

clion’s tips
The IDE tell me that something wrong.when I force IDE to compile, it also can’t compile successfully .

Below is the code of Person;

class Person{
private:
        size_t no;
        std::string name;
public:
        Person():no(0){};
        Person(size_t n): no(n){};
        Person(const Person& p):no(p.no),name(p.name){};
        friend class PersonCriterion;

    size_t getNo() const;
    void print(){
        std::cout<<no<<' ';
    }

    const std::string &getName() const;
};

class PersonCriterion{
public:
    bool operator()(const Person& p1,const Person& p2){
        return p1.no<=p2.no;
    }

};

size_t Person::getNo() const {
    return no;
}

const std::string &Person::getName() const {
    return name;
}

>Solution :

Elements got from std::set are const-qualified; they’re supposed to be non-modifiable. You should mark Person::print as const then it could be called on a const object.

class Person {
    ...
    void print() const {
    //           ^^^^^
        std::cout<<no<<' ';
    }
    ...
};

BTW: Better to mark operator() in PersonCriterion as const too.

class PersonCriterion {
public:
    bool operator()(const Person& p1, const Person& p2) const {
        return p1.no<=p2.no;
    }
};

Leave a Reply