在一个函数中重载多个运算符
overloading multiple operators in one function
是否可以在一个运算符重载中重载多个运算符?
我想做这样的事情:
template<operator O>
MyClass operator<O>(const MyClass & other) {
return this.x <O> other.x;
}
其中 x 是 class 的 int 属性。
这样就可以一次重载所有 int 运算符,这意味着我可以用一个函数重载 +、-、*、/ 等,而不是复制粘贴代码一百万次,只更改一个线.
在我的具体示例中,我有一个包含两个整数的结构 Point 和另一个包含两个浮点数的名为 Pointf 的结构,我希望能够对它们进行加法、减法、乘法和除法,或者用一个int 值,目前我用十几个函数来做,但我只想用几个函数来做,我想也覆盖 +=、-=、*- 和 /=。
不,不能在一个运算符重载中重载多个运算符。但是,您可以制作一个 class 模板以用于所有 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)
}
是否可以在一个运算符重载中重载多个运算符?
我想做这样的事情:
template<operator O>
MyClass operator<O>(const MyClass & other) {
return this.x <O> other.x;
}
其中 x 是 class 的 int 属性。
这样就可以一次重载所有 int 运算符,这意味着我可以用一个函数重载 +、-、*、/ 等,而不是复制粘贴代码一百万次,只更改一个线.
在我的具体示例中,我有一个包含两个整数的结构 Point 和另一个包含两个浮点数的名为 Pointf 的结构,我希望能够对它们进行加法、减法、乘法和除法,或者用一个int 值,目前我用十几个函数来做,但我只想用几个函数来做,我想也覆盖 +=、-=、*- 和 /=。
不,不能在一个运算符重载中重载多个运算符。但是,您可以制作一个 class 模板以用于所有 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)
}