I am learning ratio
in C++11. According to cplusplus.com and the book Professional C++ 2nd (the following paragraph is an excerpt from it).
The numerator and denominator of a rational number are represented as compile time constants of type
std::intmax_t
. Because of the compile time nature of these rational numbers, using them might look a bit complicated and different than usual. You cannot define a ratio object the same way as you define normal objects, and you cannot call methods on it. You need to usetypedefs
.
That means I have to write
typedef ratio<1,3> one_third;
instead of
ratio<1,3> one_third;
But I find that these two ways of write ratio are both working. And I can access members of ratio using either .
or ::
.
Question 1. Are the cplusplus.com and the Professional C++ book wrong?
The following snippet is from cplusplus.com example.
typedef std::ratio<1,3> one_third;
typedef std::ratio<2,4> two_fourths;
typedef std::ratio_add<one_third,two_fourths> sum;
std::cout << sum::den << std::endl;
Question 2. However, I got an error (with VS 2012)
error C2039: 'den' : is not a member of 'std::ratio_add<_R1,_R2>'
According to the comments, using typedef ratio_add<one_third, two_fourths>::type sum
is more portable.
You don't have to use typedef
s, but as the book says, <ratio>
deals with compile time math, and the meta-functions defined within it take type template arguments.
If you don't use a typedef
you're creating an instance of std::ratio<1,3>
named one_third
, which is not suitable for passing as a type argument. In that case you'll need to use decltype
to get to the appropriate type that can be passed to ratio_add
std::ratio<1,3> one_third;
std::ratio<2,4> two_fourths;
std::ratio_add<decltype(one_third), decltype(two_fourths)> sum;
std::cout << decltype(sum)::den << std::endl;
Live demo
The error message you're seeing is because the ratio_add
(and other similar meta-functions') implementation is not standard conforming on VS2012 due to lack of support for alias templates. As described in the linked bug report, the workaround is to use the nested type type
.
typedef std::ratio_add<one_third,two_fourths>::type sum;
std::cout << sum::den << std::endl;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With