In this exercise I am using Visual Studio 2017 and a modified version of the std_lib_facilities header found here.
Chapter 19 // Exercise 6
Repeat the previous exercise, but with a class Number<T> where T can be any numeric type. Try adding % to Number and see what happens when you try to use % for Number<double> and Number<int>.
During this exercise I realised that Concepts were supposed to have become a part of the standard for C++11 and C++14 but were dropped and only now are they being introduced in C++20 (they're still not here yet). Concepts would have been perfect for this exercise as it meant we could restrict Number class to only being numeric types.
I eventually ended up finding this post:
which led me to a function in <type_traits>
So you can stick a static_assert(is_arithmetic_v<T>, "that's not a numeric type") in your class. It will check at compile time if T is a numeric type and if it's not it will print out the error message in the output log instead of some horrible template error.
Very handy. Probably not as flexible as concepts however there are other useful checks you can do with functions in type_traits:
I then wanted to be able to add ints to doubles etc., like you can do with numeric types. You will get a compiler warning due to truncation but it works. As the template already restricts it to common numerical types I didn't have to bother using common_type and templated all the operator overloads to take in a different type. If it's not a numerical type it won't even compile. If you do operations on floats and ints though you get a horrible looking warning from the compiler but it runs and rounds down as expected.
As for modulo, I can't believe it's only now that I realised you can only use it for ints; it doesn't work for floating point values. You have to use fmod(). I tried to allow for it by checking if the type was floating point but the compiler doesn't really seem to care. I thought about it and even the standard double doesn't allow it so why should I?
No comments:
Post a Comment