I have a simple class template for 3D vectors:
template <typename T>
struct Vec3
{
T x, y, z; // vector components
...
}
where the template parameter T
can be int
, float
or double
(for now anyway). I have two requirements when overloading the division operator:
- it must be as efficient as possible.
- it must be available only for floating point types
I came up with this short implementation:
template <typename = std::enable_if_t<std::is_floating_point_v<T>>>
Vec3 operator/(T a) const
{
assert(a != 0);
T inva = static_cast<T>(1.0)/a;
return Vec3{inva*x, inva*y, inva*z};
}
A few questions regarding this piece of code:
- Is there another non-SFINAE way to restrict this member function to floating point types? (I am using C++17)
- Are modern compilers smart enough to compute the division first and then perform three multiplications? Is it a waste of time and expressiveness to do that myself?
Is it worth using a variable template for the constant
1.0
? Will the compiler be smart enough to do the static_cast at compile time? C++ static_cast runtime overheadtemplate<typename T> constexpr T one = T(1.0);
EDIT: gcc didn't mind, but clang wouldn't compile the code above. This is because my usage of SFINAE is incorrect. A correct implementation would be
template <typename U = T,
typename = std::enable_if_t<std::is_floating_point_v<U>>>
Vec3 operator/(T a) const
{
...
}
more details can be found here: std::enable_if to conditionally compile a member function