[英]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;
}
但是,我也有像RealNumber
, Complex
... 他們也需要重載,但只有重載<
, ==
, +
, -
, *
... 不同,而重載>
, +=
, ++
... 是相似的. (只是類型名稱差異)
所以我很好奇減少相似部分的優雅方法,我已經學習了可能有幫助的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.