I'm currently writing a templated c++ physics library. In my functions, I often have to explicitly compare or set certain numerical values. My goal is to write the library as generic as possible, therefore I want to support floating point and integer types wherever possible.
In order to get the types right, I often use an explicit cast to T
in my code. This of course is interpreted as a static_cast
in all of my cases. My question therefore is: Do I actually need to static_cast
these values? Or may I get runtime overheads by doing/not doing it?
An example:
I currently have functions like these:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = T(1)) {
return T(0) <= eccentricity < T(1) && T(0) < semi_major_axes;
}
However, I could also write it like this:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = T(1.0)) {
return T(0.0) <= eccentricity < T(1.0) && T(0.0) < semi_major_axes;
}
Like this:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = 1) {
return 0 <= eccentricity < 1 && 0 < semi_major_axes;
}
Or like this:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = 1.0) {
return 0.0 <= eccentricity < 1.0 && 0.0 < semi_major_axes;
}
I don't care much for the readability of either version. Neither do I care for the fact, that using an integer type here is probably useless. All I want to know is:
- Is there a difference between these implementations?
- If yes, what is it?
- Plus, are possible optimizations on this code compiler dependent?
Edit:
- Would any of this change, if I wanted to support custom numerical types?
Edit:
As pointed out in the comments, the chained comparison used above is actually wrong. The code should be something like:
return T(0) <= eccentricity && eccentricity < T(1) && T(0) < semi_major_axes;
Furthermore, the code could be runtime optimized by using a constexpr
version:
template <class T> constexpr auto is_elliptic(T eccentricity) {
return T(0) <= eccentricity && eccentricity < T(1);
}
template <class T> constexpr auto is_elliptic(T eccentricity, T semi_major_axes) {
return T(0) <= eccentricity && eccentricity < T(1) && T(0) < semi_major_axes;
}