Получение элемента max в векторе объектов из пользовательского класса - PullRequest
0 голосов
/ 03 октября 2018

Рассмотрим следующие блоки кода:

template<typename Prefs> class SocialPrefNode{

public:

// Constructors & Destructor
SocialPrefNode( );
SocialPrefNode( char self, std::vector<SocialPrefNode*> pref );
SocialPrefNode( const SocialPrefNode& copy );

~SocialPrefNode( );

// Setters
void set_id( char self );

void set_pref( std::vector<SocialPrefNode*> prefs );
void set_pref( SocialPrefNode& prefs );

void set_worse( std::vector<SocialPrefNode*> wrs );
void set_worse( SocialPrefNode& wrs );

void set_indiff( std::vector<SocialPrefNode*> indiff );
void set_indiff( SocialPrefNode& indiff );

// Getters
char get_id( ){ return id; }

std::vector<SocialPrefNode*> get_preferences( ){ return preferences; }
std::vector<SocialPrefNode*> get_worse( ){ return worsethan; }
std::vector<SocialPrefNode*> get_indiff( ){ return indifference; }

// Operators
SocialPrefNode& operator=( const SocialPrefNode& copy );

private:

char id{ };

std::vector<SocialPrefNode*> preferences{ };
std::vector<SocialPrefNode*> worsethan{ };
std::vector<SocialPrefNode*> indifference{ };
};

и

std::vector<SocialPrefNode<char>> graph

, где последний создается путем наведения его элементов друг на друга.

Как я могу получить максимальный элемент, с точки зрения размера настроек размера вектора, из graph ?

Т.е. я хочу выбрать элементы из graph в соответствии с размером предпочтений 'в порядке убывания.

Я рассмотрел вопрос использования std::max_element( ), но, похоже, он не применяется к вышеупомянутому коду, поскольку яиспользование вектора объектов из пользовательского класса, в котором отсутствуют свойства, для непосредственного информирования компилятора о том, что следует считать большим или меньшим элементом в векторе.

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Вы можете использовать std :: max_element с пользовательской функцией сравнения, которая сравнивает два объекта так, как вам нравится.См. перегрузка # 3 .

#include <vector>
#include <algorithm>
#include <cassert>

class Node
{
public:
    Node(const std::vector<int>& prefs) : prefs_(prefs) {}

    size_t numPrefs() const { return prefs_.size();}

    bool operator==(const Node& rhs) const { return prefs_ == rhs.prefs_;}

private:
    std::vector<int> prefs_;
};



int main(int argc, char** argv)
{
    Node one(std::vector<int>{1});
    Node two(std::vector<int>{1,2});
    Node three(std::vector<int>{1,2,3});

    std::vector<Node> nodes{one, two, three};

    auto comparison = [](const Node& a, const Node& b)
        {
            return a.numPrefs() < b.numPrefs();
        };

    auto max = std::max_element(nodes.begin(), nodes.end(), comparison);

    assert(*max == three);
    //assert(*max == two);  //Will fail
}
0 голосов
/ 03 октября 2018

По умолчанию стандартная библиотека использует operator< для сравнения объектов.Поэтому, если в вашем классе SocialPrefNode<T> есть функция или член, определенные для operator<, тогда он будет работать автоматически.

//either:
template<typename T>
bool operator<(SocialPrefNode<T> const& lhs, SocialPrefNode<T> const& rhs);

// or
template<typename T>
class SocialPrefNode
{
    public:
    bool operator<(SocialPrefNod const& rhs) const;
};

Если это невозможно, то большинство стандартных библиотечных функций позволяют указывать функцию сравнениякак последний параметр.Глядя на max_element, похоже, это имеет место https://en.cppreference.com/w/cpp/algorithm/max_element

template< class ForwardIt, class Compare >
ForwardIt max_element( ForwardIt first, ForwardIt last, Compare comp );

Третий параметр здесь используется для сравнения элементов друг с другом.Вы можете передать функцию, лямду или объект, который может сделать сравнение.

auto m = std::max_element(std::begin(graph), std::end(graph),
                          [](auto const& lhs, auto const& rhs) -> bool
                          {
                              /* Do comparison */;
                          });
...