【问题标题】:Getting the max element in a vector of objects from a custom class从自定义类中获取对象向量中的最大元素
【发布时间】:2018-10-03 20:39:51
【问题描述】:

考虑以下代码块:

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 中获取最大元素,就 preferences 向量的大小而言?

即,我想从 graph 中根据 preferences 的大小按降序选择元素。

我考虑过使用std::max_element( ),但它似乎不适用于上述代码,因为我使用的是来自自定义类的对象向量,其中没有属性可以直接通知编译器要考虑什么向量中更大或更小的元素。

感谢您的帮助。

【问题讨论】:

    标签: c++ vector max user-defined-types


    【解决方案1】:

    您可以将 std::max_element 与自定义比较函数一起使用,该函数可以根据需要比较两个对象。见overload #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
    }
    

    【讨论】:

      【解决方案2】:

      默认情况下,标准库使用operator&lt; 来比较对象。因此,如果您的类 SocialPrefNode&lt;T&gt; 具有为 operator&lt; 定义的函数或成员,那么它将自动工作。

      //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 );
      

      这里的第三个参数是用来比较元素之间的。您可以传递可以进行比较的函数、lamda 或对象。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-01
        • 2019-04-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多