c++ - 在一个函数中重载多个运算符
问题描述
是否可以在一个运算符重载中重载多个运算符?
我想做这样的事情:
template<operator O>
MyClass operator<O>(const MyClass & other) {
return this.x <O> other.x;
}
其中 x 是类的 int 属性。
这样就可以一次重载所有 int 运算符,这意味着我可以使用一个函数,重载 +、-、*、/ 等。复制粘贴代码一百万次并只更改一行。
在我的具体示例中,我有一个包含两个整数的结构点,以及另一个名为 Pointf 的结构,其中包含两个浮点数,我希望能够将它们彼此相加、相减、相乘和除法,或者使用一个 int 值,目前我用十几个函数来做,但我想只用几个函数来做,我也想覆盖 +=、-=、*- 和 /=。
解决方案
不,您不能在一个运算符重载中重载多个运算符。但是,您可以制作一个用于所有Point
s 的类模板:
#include <iostream>
template<typename T>
class Point_impl {
public:
using value_type = T;
template <typename U>
friend class Point_impl;
Point_impl() : x_{}, y_{} {} // default
Point_impl(T x, T y) : x_{x}, y_{y} {} // conversion
// create one Point_impl<T> from a Point_impl<U>
template<typename U>
Point_impl(const Point_impl<U>& rhs) :
x_{static_cast<T>(rhs.x_)},
y_{static_cast<T>(rhs.y_)}
{}
T get_x() const { return x_; }
T get_y() const { return y_; }
// add a Point_impl<U> to *this
template<typename U>
Point_impl<T>& operator+=(const Point_impl<U>& rhs) {
x_ += static_cast<U>(rhs.x_);
y_ += static_cast<U>(rhs.y_);
return *this;
}
template<typename U>
Point_impl<T>& operator-=(const Point_impl<U>& rhs) {
x_ -= static_cast<U>(rhs.x_);
y_ -= static_cast<U>(rhs.y_);
return *this;
}
template<typename U>
Point_impl<T>& operator*=(const Point_impl<U>& rhs) {
x_ *= static_cast<U>(rhs.x_);
y_ *= static_cast<U>(rhs.y_);
return *this;
}
template<typename U>
Point_impl<T>& operator/=(const Point_impl<U>& rhs) {
x_ /= static_cast<U>(rhs.x_);
y_ /= static_cast<U>(rhs.y_);
return *this;
}
// for printing a point:
friend std::ostream& operator<<(std::ostream& os, const Point_impl<T>& p) {
return os << '(' << p.x_ << ',' << p.y_ << ')';
}
private:
T x_, y_;
};
然后可以像这样完成使用不同底层类型操作的自由函数:
template<typename L, typename R>
auto operator+(const Point_impl<L>& lhs, const Point_impl<R>& rhs) {
// return the properly promoted Point_impl type deduced from if the
// underlying types were added
Point_impl<decltype(lhs.get_x() + rhs.get_x())> rv = lhs;
rv += rhs;
return rv;
}
template<typename L, typename R>
auto operator-(const Point_impl<L>& lhs, const Point_impl<R>& rhs) {
Point_impl<decltype(lhs.get_x() - rhs.get_x())> rv = lhs;
rv -= rhs;
return rv;
}
template<typename L, typename R>
auto operator*(const Point_impl<L>& lhs, const Point_impl<R>& rhs) {
Point_impl<decltype(lhs.get_x() * rhs.get_x())> rv = lhs;
rv *= rhs;
return rv;
}
template<typename L, typename R>
auto operator/(const Point_impl<L>& lhs, const Point_impl<R>& rhs) {
Point_impl<decltype(lhs.get_x() / rhs.get_x())> rv = lhs;
rv /= rhs;
return rv;
}
为方便起见,您还可以添加别名:
using Point = Point_impl<int>;
using Pointl = Point_impl<long>;
using Pointf = Point_impl<float>;
using Pointd = Point_impl<double>;
using Pointld = Point_impl<long double>;
例子:
#include <type_traits>
int main()
{
Point x(1,2); // Point_impl<int>
Pointf y(3.141f,6.282f); // Point_impl<float>
auto z = x + y; // int + float => Point_impl<float>
std::cout << std::is_same<decltype(z), Pointf>::value << '\n'; // prints 1
std::cout << z << '\n'; // (4.141,8.282)
}
推荐阅读
- python - 连接列表中的整数并打印它,而不使用 python for 循环
- javascript - 如何将变量从python3传递到javascript?
- javascript - 我如何让 npm 在隐身模式下开始打开 chrome 或在开发过程中避免缓存?
- java - 为什么在 Java BlockingQueue 中没有关于通知的 if 子句?
- json.net - DataBusProperty 上的 NServiceBus MessageDeserializationException
- php - 替换php中字符串的前两个字符
- mysql - 在后端开发中,将图像文件以 URL 或 LongBlob 的形式存储在 mysql 数据库中更好吗?
- android - 如何使用指定字段的 gson 将 POJO 对象转换为 json 字符串?
- excel - 如何找到另一个工作簿中范围的最大值和最小值?
- sql-server - 慢查询根据状态从表中获取最大和最小日期