Dylan Czenski
Dylan Czenski

Reputation: 1365

Iterator for const list<t> in C++

I wrote this non-member function for finding members with the maximum and minimum values of level (a float property). My logic is push back all levels from vipList to a vector, and calculate using std::max_element and std::min_element, and return a std::pair that contains those 2 values:

pair<float,float> minMax (const list<member>& vipList){
    vector<float> v(vipList.size());
    for (list<member>::iterator it = vipList.begin(); it!=vipList.end(); ++it) //error
    {
        v.push_back(it->level);
    }
    return std::make_pair(*std::max_element(std::begin(v),std::end(v)),*std::min_element(std::begin(v),std::end(v)));
}

the error message is:

no suitable user-defined conversion from "std::_List_const_iterator<std::_List_val<std::_List_simple_types<member>>>" to "std::_List_iterator<std::_List_val<std::_List_simple_types<member>>>" exists

So I changed list<member>::iterator it to std::_List_const_iterator<member> it and that does not work either. If I remove const from the parameter, it builds, but that is not what I wanted. Can some one please help? Thank you.

Upvotes: 3

Views: 4208

Answers (1)

NathanOliver
NathanOliver

Reputation: 180500

Since vipList is a const list<member>& you need to use list<member>::const_iterator as that is what begin() will return. You could also use auto and let the compiler pick the right type.

Instead of doing all of this we could just use std::minmax_element which will return a pair of iterators the min and max values. We can do that with the list using a lambda like

return std::minmax_element(vipList.begin(), vipList.end(), [](const member & lhs, const member& rhs) { return lhs.level < rhs.level; });

This will return a std::pair<std::list<member>::const_iterator, std::list<member>::const_iterator>. If you want it to return a std::pair<float, float> then we need to capture the return of std::minmax_element and dereference the iterators to get the underlying floats.

auto ip = std::minmax_element(vipList.begin(), vipList.end(), [](const member & lhs, const member& rhs) { return lhs.level < rhs.level; });
return std::make_pair(ip.first->level, ip.second->level);

Upvotes: 3

Related Questions