# Boost :

Subject: Re: [boost] [ratio] Assignation between equivalent ratios
From: Howard Hinnant (howard.hinnant_at_[hidden])
Date: 2009-12-06 17:42:20

On Dec 6, 2009, at 1:33 PM, vicente.botet wrote:

> Hi,
>
> I was wondering if we need to be able to make assignations between equivalent ratios. e.g.
>
> ratio<1,3> r1;
>
> ratio<3,9> r2;
>
> r1 = r2; // (1)
>
>
> Reading N3000 even if they are equivalents (synonym ) as its num and den are the same, there is no defined assignation. So (1) should not compile with the current recomendation.
>
> IMO, this should compile, and so we need to add a specific assignement operator.
>
> Other example
>
> ratio<1,3> r1;
>
> ratio<2,3> r2;
>
> r1 = r2-r1; // the type of this expression could be ratio<3,9> so the compilation fails.
>
> Otherwise the recomendation should clarify the meaning of synonym on the ratio arithmetic operators
> [ratio.arithmetic] 2
>
> "The nested typedef type shall be a synonym for ratio<T1, T2> where T1 has the value R1::num *
>
> R2::den + R2::num * R1::den and T2 has the value R1::den * R2::den."
>
> Maybe we should talk of normalized ratio and not of synonym. BTW, where is synonym defined?
>
> In addition I think that we need also to add that the declaration of no normalized ratios, as ratio<3,9>, must fail at compile time as it is not normalized and we can not assigne nothing to them.
>
> I'm missing something? Any thougths?

Hi Vicente,

I think you've made a good observation. The original intent was to just have the special members of <ratio> governed by [functions.within.classes]. However your example code has given me pause for thought. I haven't found any motivating use cases for the assignment operator. But I can easily think of motivating uses for the copy constructor (and having the assignment operator be consistent, with the copy constructor, motivating cases or not, makes sense). I'm experimenting with the following special members and things look good to me:

ratio() {}

template <intmax_t _N2, intmax_t _D2>
ratio(const ratio<_N2, _D2>&,
typename enable_if
<
ratio<_N2, _D2>::num == num &&
ratio<_N2, _D2>::den == den
>::type* = 0) {}

template <intmax_t _N2, intmax_t _D2>
typename enable_if
<
ratio<_N2, _D2>::num == num &&
ratio<_N2, _D2>::den == den,
ratio&
>::type
operator=(const ratio<_N2, _D2>&) {return *this;}

I.e. ratio is default constructible, and can be constructed or assigned from any ratio which has the same normalized form.

I encourage you to write up an issue for the LWG issues list proposing this addition. Instructions for doing so can be found here:

Thanks for working on this.

-Howard