代码之家  ›  专栏  ›  技术社区  ›  Carbon

C++无序对类型

  •  0
  • Carbon  · 技术社区  · 7 年前

    unordered_set

    class unordered_pair : public std::pair<t, u>
    {
    public:
        unordered_pair(t x, u y) : std::pair<t, u>(x,y) {};
        bool operator ==(const unordered_pair<t,u>& rhs)
        {
            if ((this->first < this->second) ^ (rhs.first < rhs.second))
            {
                return this->second == rhs.first && this->first == rhs.second;
            }
            else
            {
                return this->first == rhs.first && this->second == rhs.second;
            }
        }
    };
    
    3 回复  |  直到 7 年前
        1
  •  3
  •   UKMonkey    7 年前

    我想做点什么

    struct unordered_pair : std::pair<t, u>
    {
        bool swapped;
    
        unordered_pair(t x, u y) : 
            std::pair<t, u>(x,y),
            swapped(false);
        {
            sort();
        }
    
        void sort() {
            swapped = first > second;
            if (swapped)
                std::swap(first, second);
        }
    
        std::pair<t, u> getOrig() {
            if (swapped)
                return std::pair<t,u>(second, first);
            return std::pair<t, u>(first, second);
        }
    }
    

    然后,每次调用第一或第二个时,只需调用SoRT(),所有的比较运算符都是从STD::对免费获得的!

    其动机是,如果你不关心比较的顺序,那么大多数时候你不会关心顺序;这意味着大多数时候,你不需要得到原始项目。

    编辑:您在注释中声明,我们可以假定t==u…如果是那样的话,我建议你把T或U去掉,然后就这样做。 std::pair<t, t>

        2
  •  2
  •   Caleth    7 年前

    让我们在这个模板中填充一些类型(您省略了 template ,没有声明 t u )并查看它试图实例化的内容

    unordered_pair<int, std::string> pair, pair2;
    
    bool operator ==(const unordered_pair<t,u>& rhs)
    {
        if ((this->first < this->second) ^ (rhs.first < rhs.second))
    

    这是 bool operator <(int, std::string) bool operator <(std::string, int) .这些不存在。

        {
            return this->second == rhs.first && this->first == rhs.second;
        }
    

    这是 bool operator ==(int, std::string) bool operator ==(std::string, int) .这些也不存在。

        else
        {
            return this->first == rhs.first && this->second == rhs.second;
        }
    }
    

    你反而想要 模板类型参数。试试这个

    class bad_unordered_pair : public std::exception
    {
        const char * what() const { return "unordered_pair must have exactly two distinct values"; }
    }
    
    template <typename T>
    std::pair<T, T> make_unordered_pair(T first, T second)
    {
        std::hash<T> hash;
        if (first == second) throw bad_unordered_pair{};
        if (hash(first) < hash(second)) return unordered_pair(first, second);
        return unordered_pair(second, first);
    }
    
        3
  •  1
  •   Toby Speight    7 年前

    旁白 :我想你的意思是

    template<typename t>
    class unordered_pair : public std::pair<t, t>
    

    因为如果成员应该是可互换的,那么他们是不同类型的成员是没有意义的。


    sorted() 方法,以便于写入这些重载:

    private:
        std::tuple<t const&, t const&> ordered() const noexcept
        {
            return (this->first < this->second)
                ? std::tie(this->first, this->second)
                : std::tie(this->second, this->first);
        }
    };
    

    == <

    bool operator ==(const unordered_pair<t>& rhs) const noexcept
    {
        return ordered() == rhs.ordered();
    }
    bool operator <(const unordered_pair<t>& rhs) const noexcept
    {
        return ordered() < rhs.ordered();
    }
    

    bool operator !=(const unordered_pair<t>& rhs) const noexcept
    {
        return !(*this == rhs);
    }
    
    bool operator >(const unordered_pair<t>& rhs) const noexcept
    {
        return rhs < *this;
    }
    
    bool operator <=(const unordered_pair<t>& rhs) const noexcept
    {
        return !(rhs < *this);
    }
    
    bool operator >=(const unordered_pair<t>& rhs) const noexcept
    {
        return !(*this < rhs);
    }
    

    或者,如果你有C++ 20,那么实现 <=>

    template<typename T>
    class unordered_pair : public std::pair<T, T>
    {
    public:
        unordered_pair(T x, T y)
            : std::pair<T, T>(x,y)
        {}
    
        std::strong_ordering operator<=>(const unordered_pair<T>& other)
        {
            return ordered() <=> other.ordered();
        }
    
    private:
        std::tuple<T const&, T const&> ordered() const noexcept
        {
            return (this->first < this->second)
                ? std::tie(this->first, this->second)
                : std::tie(this->second, this->first);
        }
    };
    

    或者甚至将助手吸收到操作员中:

    std::strong_ordering operator<=>(const unordered_pair<T>& other)
    {
        auto ordered = [](unordered_pair<T> const& t) {
            return (t.first < t.second)
            ? std::tie(t.first, t.second)
            : std::tie(t.second, t.first);
        };
    
        return ordered(*this) <=> ordered(other);
    }