我们以一个表示区间的简单类为例。我希望它支持以下操作:
int main()
{
Interval<double> i1(1, 2);
Interval<double> i2(3, 4);
i1 + 1.0;
1.0 + i1;
i1 + 1.0f;
1.0f + i1;
i1 + 1;
1 + i1;
i1 + i2;
}
一个可能的实现是
template<typename Real>
class Interval
{
public:
Interval(Real value)
: lower(value), upper(value)
{ }
template<typename Real2>
Interval(Real2 value)
: lower(value), upper(value)
{ }
template<typename Real2>
Interval(Real2 l, Real2 u)
: lower(l), upper(u)
{ }
Interval<Real>& operator += (Interval<Real> rhs)
{
lower += rhs.lower;
upper += rhs.upper;
return *this;
}
private:
Real lower, upper;
};
template<typename Real>
const Interval<Real> operator + (Interval<Real> i1, const Interval<Real>& i2)
{
i1 += i2;
return i1;
}
template<typename Real1, typename Real2>
const Interval<Real1> operator + (Interval<Real1> i1, const Real2& r2)
{
i1 += r2;
return i1;
}
template<typename Real1, typename Real2>
const Interval<Real2> operator + (const Real1& r1, Interval<Real2> i2)
{
i2 += r1;
return i2;
}
这有一些代码重复。有没有更“经济”的实现方式?最佳做法是什么?
最佳答案
<罢工>
您可以通过在 Interval
中提供构造函数来最小化重载函数的数量。只接受一个 Real
类型的参数.罢工>
然后,您需要实现的是:
template <typename Real>
Interval<Real> operator+(Interval<Real> const& lhs, Interval<Real> const& rhs)
罢工><罢工>罢工>
更新
如果我有一个成员函数:
Interval operator + (const Interval& i2)
{
Interval<Real> i1 = *this;
i1 += i2;
return i1;
}
然后,我就可以编译了:
Interval<double> i1(1, 2);
Interval<double> i2(3, 4);
std::cout << (i1 + i2) << std::endl;
std::cout << (i1 + 1.0) << std::endl;
std::cout << (i1 + 1.0f) << std::endl;
std::cout << (i1 + 1) << std::endl;
但是如果我有一个免费的功能:
template<typename Real>
Interval<Real> operator + (Interval<Real> i1, const Interval<Real>& i2)
{
i1 += i2;
return i1;
}
然后,我得到编译器错误:
std::cout << (i1 + 1.0) << std::endl;
std::cout << (i1 + 1.0f) << std::endl;
std::cout << (i1 + 1) << std::endl;
我不知道为什么会这样。
更新 2
感谢@MooingDuck,很清楚为什么自由函数不起作用但成员函数适用于上述行。
作为成员函数,没有模板推导,因此转换开始发挥作用。作为免费功能,有模板推导,不允许用户转换。
关于c++ - 重载加法运算符时代码重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24414490/