C++ 如何优化过载操作员<&燃气轮机<;=>;=但是只写一个或两个比较函数?

C++ 如何优化过载操作员<&燃气轮机<;=>;=但是只写一个或两个比较函数?,c++,comparison,operator-overloading,C++,Comparison,Operator Overloading,我有一个属性类型为std::string的类。我想通过比较属性为类提供一些比较运算符函数,如,==,=等 我的问题是:任何简单的方法或工具 (1) 只需编写一个或两个函数,例如运算符(在类的命名空间中使用namespace std::rel_ops是不可接受的,因为ADL不会提取它) 一种选择是使用CRTP,如Barton-Nackman技巧: //表示相等比较接口的类模板。 模板类相等\u可比{ 友元布尔运算符==(T常量&a,T常量&b){返回a.equal_到(b);} 友元布尔运算符

我有一个属性类型为std::string的类。我想通过比较属性为类提供一些比较运算符函数,如,==,=等

我的问题是:任何简单的方法或工具

(1) 只需编写一个或两个函数,例如运算符<(和==)的函数,其他函数可以自动生成

(2) 或者更简单,因为类比较取决于其类型
std::string
的属性,该属性的比较函数已经提供。

奇怪的重复模板模式 在本例中,您提供了一个简单的基类,该基类实现了所有需要的运算符,并简单地从中继承:

template <class T>
struct implement_relational_operators{
    friend bool operator<=(const T & a,const T & b){ return a < b || a == b; }
    friend bool operator>(const T &  a, const T & b){ return !(a <= b); }
    friend bool operator!=(const T &  a, const T & b){ return !(a == b);}
    friend bool operator>=(const T &  a, const T & b){ return !(a < b); }
};

template <class T>
struct scalar : public implement_relational_operators<scalar<T> >{
    T value;
    bool operator<(const scalar& o) const { return value < o.value;}
    bool operator==(const scalar& o) const { return value == o.value;}
};
请注意,这些比手写效率低

警告 然而,因为自己提供这些操作符很容易,所以您只需付出额外的努力并编写它们。它们也有一些缺点,如下所述:

请注意,除非您:

  • 在您使用运算符的每个上下文上使用名称空间std::rel_ops添加
    ;或
  • 使用::运算符添加
    ;使用::运算符=;使用::运算符>
    在类的命名空间中使用namespace std::rel_ops
    是不可接受的,因为ADL不会提取它)

  • 一种选择是使用CRTP,如Barton-Nackman技巧:

    //表示相等比较接口的类模板。
    模板类相等\u可比{
    友元布尔运算符==(T常量&a,T常量&b){返回a.equal_到(b);}
    友元布尔运算符!=(T常数&a,T常数&b){返回!a.等于(b);}
    };
    类值类型
    //类值\u type希望具有==和!=,所以它来自于
    //equal_作为参数与自身可比(即CRTP)。
    :私人同等{
    公众:
    bool equal_to(value_type const&rhs)const;//待定义
    };
    
    您可以使用
    std::rel_ops
    ,但这是错误的。这是一把大锤,不属于任何人的工具箱

    通常的方法是定义
    操作符==
    操作符=b
    !(a

    (如果您可以控制该类),正确的方法是使用Boost.Operators


    如果您只有
    @dialogicus:While这是真的(并且
    注意,除非您:1)在您使用运算符的每个上下文上使用名称空间std::rel_ops添加
    (这不是很好);或者2)使用::运算符添加
    ;使用::运算符=;使用::运算符>
    在类名称空间中使用名称空间std::rel_ops
    是不可接受的,因为它不会被ADL拾取)。@R.MartinhoFernandes,这就是std::rel_ops在C++20中被弃用的原因吗?(请参阅)@alfC-see(设计
    )和(图书馆建议书)了解原因。对于
    rel_ops
    ,您需要两个函数,而P0512描述了一个新的
    操作符,它一次处理所有情况,并且可以用于迄今为止由
    rel_ops
    提供的其他操作符<因此,由于有更好的替代方案,代码>相关操作将被弃用。今天晚些时候我会更新我的答案。事实上,即使是
    =
    也可以用
    @Casey来编写-这种模式的要点是能够编写
    =
    ==
    方面,并且,当还需要不等式时,能够用
    编写各种不等式是的,很抱歉。在我意识到您交换了参数之前,我点击了“添加”。你所做的比较没有错。
    
    a != b equal to !(a == b)
    a <= b equal to (a < b) || (a == b)
    a >= b equal to !(a < b)
    a >  b equal to !(a <= b)
    
    // A class template to express an equality comparison interface.
    template<typename T> class equal_comparable {
        friend bool operator==(T const &a, T const &b) { return  a.equal_to(b); }
        friend bool operator!=(T const &a, T const &b) { return !a.equal_to(b); }
    };
    
    class value_type
     // Class value_type wants to have == and !=, so it derives from
     // equal_comparable with itself as argument (which is the CRTP).
     : private equal_comparable<value_type> {
      public:
        bool equal_to(value_type const& rhs) const; // to be defined
    };
    
    #include<cassert>
    #include<boost/operators.hpp>
    
    struct A : boost::totally_ordered<A> // implies equality-comparable and less-than-comparable
    {
        int val_;
        A(int const& v) : val_{v}{}
        bool operator==(A const& other) const{return other.val_ == val_;}
        bool operator<(A const& other) const{return other.val_ < val_;}
    };
    
    int main(){
        A a1{5};
        A a2{7};
    
        assert(!(a1 == a2)); // user defined operator==
        assert(a1 != a2);    // automatically defined !=
        assert(a1 < a2);     // user defined operator<
        assert(a2 > a1);     // automatically defined >
        assert(a2 >= a1);    // automatically defined >=
        assert(a1 <= a2);    // automatically defined <=
    }
    
    #include<boost/operators.hpp>
    
    struct A : boost::totally_ordered<A>, boost::equivalent<A>{
        int val_;
        A(int const& v) : val_{v}{}
        bool operator<(A const& other) const{return other.val_ < val_;}
    };