简体   繁体   English

减少 C++ 中不必要的运算符重载

[英]reduce unnecessary operator overloading in C++

After I overloaded < , == , + , - , * ... in a class named Fraction :在我重载< , == , + , - , * ... 在名为Fraction的 class 中:

class Fraction:
public:
    // constructor, operator= ... defined before
    bool operator<(const Fraction& A) const;
    bool operator==(const Fraction& A) const;
    Fraction operator+(const Fraction& A) const;
    Fraction operator-(const Fraction& A) const;
    Fraction operator*(const Fraction& A) const;
    Fraction operator/(const Fraction& A) const;

I could use these above 'basic' operators to overload > , += , ++ and + from left...我可以使用上面的这些“基本”运算符来重载>+=+++从左...

class Fraction:
public:
    bool operator>(const Fraction& A) const {
        return A < *this;
    }
    bool operator!=(const Fraction& A) const {
        return !(*this == A);
    }
    Fraction &operator+=(const Fraction& A) const {
        return *this = *this + A;
    }
    Fraction operator++() const {
        return *this += 1;
    }
    friend Fraction &operator+(const int& a, const Fraction& A) const {
        return A + a;
    }

However, I also have classes like RealNumber , Complex ... They also need overloading, but only overloading < , == , + , - , * ... differs, while overloading > , += , ++ ... is similar.但是,我也有像RealNumberComplex ... 他们也需要重载,但只有重载<==+-* ... 不同,而重载>+=++ ... 是相似的. (just a typename difference) (只是类型名称差异)

So I'm curious about an elegant way to reduce the similar part, I've learnt the CRTP that possible helps, but it only overloads comparison...所以我很好奇减少相似部分的优雅方法,我已经学习了可能有帮助的CRTP ,但它只会重载比较......

Use a CRTP base class like boost::operators to define the boring bits.使用类似boost::operators的 CRTP 基础 class 来定义钻孔位。 You just define the methods below, and it automatically adds all the other operators for you.您只需定义以下方法,它会自动为您添加所有其他运算符。

class Fraction {
    : boost::operators<Fraction>
public:
    bool operator<(const Fraction& x) const {...}
    bool operator==(const Fraction& x) const {...}
    Fraction& operator+=(const Fraction& x) {...}
    Fraction& operator-=(const Fraction& x) {...}
    Fraction& operator*=(const Fraction& x) {...}
    Fraction& operator/=(const Fraction& x) {...}
    Fraction& operator%=(const Fraction& x) {...}
    Fraction& operator|=(const Fraction& x) {...}
    Fraction& operator&=(const Fraction& x) {...}
    Fraction& operator^=(const Fraction& x) {...}
    Fraction& operator++() {...}
    Fraction& operator--() {...}
}

https://www.boost.org/doc/libs/1_41_0/libs/utility/operators.htm https://www.boost.org/doc/libs/1_41_0/libs/utility/operators.htm

You may be interested in the three-way comparison operator (Also known as the space ship operator):您可能对三路比较算子(也称为太空船算子)感兴趣:

It does however require C++20但是它确实需要C++20

It won't reduce all the operators you will have to write.它不会减少您必须编写的所有运算符。 But at least the comparison operators you have to write are reduced.但至少您必须编写的比较运算符减少了。

If we are talking about C++20, then如果我们谈论的是 C++20,那么

/* some type traits */
namespace detail {
    template <typename T> struct is_number_helper : public std::false_type {};
    template <> struct is_number_helper<Fraction> : public std::true_type  {};
    /* do for every number class */
}

template <typename T>
inline constexpr bool is_number = detail::is_number_helper<std::remove_cv_t<T>>::value;

/* concept */
template <typename T>
concept Number = is_number<T>;

/* generic operator (for all Number types) */

template <Number N>
constexpr N operator + (const N& lhs, const N& rhs) { /*...*/ }
/* ... */

/* specialized operator */

constexpr Complex operator + (const Complex& lhs, const Complex& rhs) { /*...*/ }
/* ... */

If you don't specialize an operator, the generic one will be used, if there is a specialized operator, then that.如果您不专门化运算符,则将使用通用运算符,如果有专门的运算符,则使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM