簡體   English   中英

減少 C++ 中不必要的運算符重載

[英]reduce unnecessary operator overloading in C++

在我重載< , == , + , - , * ... 在名為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;

我可以使用上面的這些“基本”運算符來重載>+=+++從左...

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;
    }

但是,我也有像RealNumberComplex ... 他們也需要重載,但只有重載<==+-* ... 不同,而重載>+=++ ... 是相似的. (只是類型名稱差異)

所以我很好奇減少相似部分的優雅方法,我已經學習了可能有幫助的CRTP ,但它只會重載比較......

使用類似boost::operators的 CRTP 基礎 class 來定義鑽孔位。 您只需定義以下方法,它會自動為您添加所有其他運算符。

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

您可能對三路比較算子(也稱為太空船算子)感興趣:

但是它確實需要C++20

它不會減少您必須編寫的所有運算符。 但至少您必須編寫的比較運算符減少了。

如果我們談論的是 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) { /*...*/ }
/* ... */

如果您不專門化運算符,則將使用通用運算符,如果有專門的運算符,則使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM