Find elements of std::set by custom comparison with value of different type

前端 未结 1 1628
梦谈多话
梦谈多话 2020-12-20 16:25

Consider the following toy example of an std::set with a custom comparator:

#include 

struct A {
  A() : a(cnt++) {}
  const int a;
         


        
1条回答
  •  温柔的废话
    2020-12-20 16:47

    With C++14 you can utilize "transparent" comparator:

    #include 
    #include 
    #include 
    
    class A
    {
        public: explicit A() : a{cnt++} {}
        private: explicit A(int) = delete;
        public: const int a;
        private: static int cnt;
    };
    
    int A::cnt{};
    
    class Comparator
    {
        // this member is required to let container be aware that 
        // comparator is capable of dealing with types other than key
        public: using is_transparent = std::true_type;
    
        public: bool operator()(const int & left, const A& right) const
        {
            return left < right.a;
        }
    
        public: bool operator()(const A & left, const int& right) const
        {
            return left.a < right;
        }
    
        public: bool operator()(const A& left, const A& right) const
        {
            return left.a < right.a;
        }
    };
    
    int main()
    {
        std::set sa{};
        for (int i{}; i < 10; ++i)
        {
            sa.emplace();
        }
        std::cout << sa.find(3)->a << std::endl;
        return 0;
    }
    

    online compiler

    Before C++14 heterogenous lookup was available in ::boost::intrusive::set:

    #include 
    #include 
    
    namespace bi = ::boost::intrusive;
    
    // hook contains set node data, supports various options, can be a member
    class A: public bi::set_base_hook
    <
        bi::link_mode
    >
    {
        public: explicit A() : a{cnt++} {}
        private: explicit A(int) = delete;
        public: const int a;
        private: static int cnt;
    };
    
    int A::cnt{};
    
    class Comparator
    {
        public: bool operator()(const int & left, const A& right) const
        {
            return left < right.a;
        }
    
        public: bool operator()(const A & left, const int& right) const
        {
            return left.a < right;
        }
    
        public: bool operator()(const A& left, const A& right) const
        {
            return left.a < right.a;
        }
    };
    
    int main()
    {
        bi::set> sa{Comparator{}};
        for (int i{0}; i < 10; ++i)
        {
            sa.insert(*new A{}); // typically user manages object creation
        }
        // comparators may vary
        std::cout << sa.find(3, Comparator{})->a << std::endl;
        return 0;
    }
    

    online compiler

    0 讨论(0)
提交回复
热议问题