我们以一个表示区间的简单类为例。我希望它支持以下操作:
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;
}
这有一些代码重复。是否有更“经济”的实施?什么是最佳做法?
答案 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,很清楚为什么免费功能不起作用,但成员函数适用于上述行。
作为会员功能,没有模板扣除,因此转换发挥作用。作为免费功能,有模板扣除,不允许用户转换。