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)
Even if they are equivalents (synonym ) as its num and den are the
same, there is no defined assignation in N3000. So (1) should not
compile with the current recommendation.
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.
IMO, this should compile, and so we need to add a specific assignment
operator.
Otherwise the recommendation should clarify the meaning of synonym on
the ratio arithmetic operators
[ratio.arithmetic] 3
"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>, should fail at compile time as if
we allows them we can not assign any arithmetic expression if
arithmetic operator can normalize normalize.
I'm missing something? Any thoughts?
Best regards
_____________________
Vicente Juan Botet Escrib�
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
> 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)
>
>
> Even if they are equivalents (synonym ) as its num and den are the
> same, there is no defined assignation in N3000. So (1) should not
> compile with the current recommendation.
True, but that doesn't matter. std::ratio does not hold any values, so
runtime assignments and so forth don't make any sense. Either the values
are equivalent, so assignment is unnecessary, or they are not, so
assignment can't work.
> 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.
Runtime subtraction using operator- is not defined for std::ratio. It is
for compile-time arithmetic only. Ratio subtraction is defined with
std::ratio_sub<R1,R2>::type. The result is defined to be over the lowest
common denominator, so ratio_sub<ratio<2,3>,ratio<1,3>>::type is
ratio<1,3>
> Otherwise the recommendation should clarify the meaning of synonym on
> the ratio arithmetic operators
>
> [ratio.arithmetic] 3
>
> "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?
Synonym takes on its usual meaning: a word that means the same as
another word. Thus using ratio_sub<ratio<2,3>,ratio<1,3>>::type "means
the same" as using ratio<1,3> i.e. it is the same type.
> In addition I think that we need also to add that the declaration of
> no normalized ratios, as ratio<3,9>, should fail at compile time as if
> we allows them we can not assign any arithmetic expression if
> arithmetic operator can normalize normalize.
There is no runtime assignment or operations, and all compile-time
arithmetic is defined to take care of denormalized ratios, so this is
not a problem.
Anthony
--
Author of C++ Concurrency in Action http://www.stdthread.co.uk/book/
just::thread C++0x thread library http://www.stdthread.co.uk
Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
Agreed. However a converting copy constructor with this behavior
might be very useful for tag dispatching:
void foo(ratio<1, 4>); // handle 1/4 cases
void foo(ratio<1, 2>); // handle 1/2 cases
void foo(ratio<3, 4>); // handle 3/4 cases
It would be unfortunate if foo(ratio<75, 100>()) did not compile.
Especially if the 75 and 100 were the result of an encapsulated
compile-time computation instead of literals. And if it is useful to
have this converting copy constructor (and I believe it is), then I
think the assignment should be consistent if only for consistency's
sake.
-Howard
--
See Howard reply.
> > 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.
>
> Runtime subtraction using operator- is not defined for std::ratio. It is
> for compile-time arithmetic only. Ratio subtraction is defined with
> std::ratio_sub<R1,R2>::type. The result is defined to be over the lowest
> common denominator, so ratio_sub<ratio<2,3>,ratio<1,3>>::type is
> ratio<1,3>
You are right. I misused the operator-. I don't see where N3000 says
that "the result of std::ratio_sub<R1,R2>::type is defined to be over
the lowest common denominator". Could you point me where? It says
"template <class R1, class R2> struct ratio_subtract {
typedef see below type;
};
3 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.
"
> > Otherwise the recommendation should clarify the meaning of synonym on
> > the ratio arithmetic operators
>
> > [ratio.arithmetic] 3
>
> > "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?
>
> Synonym takes on its usual meaning: a word that means the same as
> another word. Thus using ratio_sub<ratio<2,3>,ratio<1,3>>::type "means
> the same" as using ratio<1,3> i.e. it is the same type.
This is common sense, but the text in N3000 don't force this. I
understand that ratio<1,3> could be a synonym for ratio<3,9>, but, why
ratio<3,9> is not a synonym of itself? I proposed something like
The nested typedef type shall be a synonym for ratio<T1,
T2>***:type*** where T1
has the value R1::num * R2::den - R2::num * R1::den and T2 has the
value R1::den * R2::den.
and the nested typedef type represent the normalized ratio and defined
as follows
template <intmax_t T1, intmax_t T2>
ratio {
...
typedef ratio<num,den> type; // normalized type.
}
> > In addition I think that we need also to add that the declaration of
> > no normalized ratios, as ratio<3,9>, should fail at compile time as if
> > we allows them we can not assign any arithmetic expression if
> > arithmetic operator can normalize normalize.
>
> There is no runtime assignment or operations, and all compile-time
> arithmetic is defined to take care of denormalized ratios, so this is
> not a problem.
You are right there is no run-time operator on the ratio class, but at
least there is the default assignement. Forget this point, I have
extrapolated from another example which had runtime operators.
The example I had in mind was a class quantity
template <class R1, class R2> // R1 R2 are ratio classes
class quantity
{
double q_;
public:
typedef R1 time_dim;
typedef R2 distance_dim;
quantity() : q_(1) {}
double get() const {return q_;}
void set(double q) {q_ = q;}
};
// other specializations adding specific constructors
typedef quantity<boost::ratio<1>, boost::ratio<0> > Time; //
second
typedef quantity<boost::ratio<0>, boost::ratio<1> > Distance; //
meter
typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed; //
meter/second
template <class R1, class R2, class R3, class R4>
quantity<typename boost::ratio_subtract<R1, R3>::type, typename
boost::ratio_subtract<R2, R4>::type>
operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y);
Distance d( mile(110) );
Time t( boost::chrono::hours(2) );
Speed s= d / t;
If boost::ratio_subtract<R1, R3>::type is not normalized this do not
compiles.
Now suppose the boost::ratio_subtract<R1, R3>::type is normalized.
Do we want the following compile?
quantity<boost::ratio<-2>, boost::ratio<2> > s= d / t;
If yes we need to add assignment operator able to assign equivalent
types.
If not we should forbid the declaration of quantity<boost::ratio<-2>,
boost::ratio<2> > at compile time as nothing can be done with.
> Anthony
> --
Vicente
--