重载加法运算符时的代码重复

时间:2014-06-25 16:54:13

标签: c++ operator-overloading

我们以一个表示区间的简单类为例。我希望它支持以下操作:

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

这有一些代码重复。是否有更“经济”的实施?什么是最佳做法?

1 个答案:

答案 0 :(得分:1)

<击> 您可以通过在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,很清楚为什么免费功能不起作用,但成员函数适用于上述行。

作为会员功能,没有模板扣除,因此转换发挥作用。作为免费功能,有模板扣除,不允许用户转换。