Literals in Template Function for Floating Point Types

This question has come up before, especially here Should we generally use float literals for floats instead of simpler double literals? but I was wondering if there are any better suggested solutions now we are in C ++ 14 and there are things like custom literals and parenthesis initialization.

The problem can be expressed in how to write a floating literal in a template function for floating point types

template <typename T> T foo( T x )
{
    static_assert( std::is_floating_point<T>::value, "" );

    T y = x * 101.0;

    return( y );
}

      

So the question comes down to how we write "101.0" since it stands on double, and what happens if I call foo using

float a = 42.0f;
float b = foo( a );

      

If I write "101.0f" to foo, what happens if I call foo with double, note 101.0 and 101.0f are not necessarily the same.

Also, how can I ensure that no extra code is generated to return values?

Other suggestions include writing things like "static_cast (101.0)", "T (101.0)" or some other nasty stuff!

+3


source to share


2 answers


A C ++ 14-specific option will use the variable pattern

namespace detail
{
    template<typename F>
    F multiplier = F(101.0);
}

template <typename T> T foo( T x )
{
    static_assert( std::is_floating_point<T>::value, "" );

    T y = x * detail::multiplier<T>;

    static_assert(std::is_same<decltype(detail::multiplier<T>), T>{}, "");

    return( y );
}

      



Live demo

+2


source


template <typename T> T foo( T x ){
  static_assert( std::is_floating_point<T>::value, "" );

  T y = x * foo_constants<T>::one_o_one;

  return( y );
}

      

Then just define and specialize your constants in the struct foo_constants

.



You probably won't need a static argument anymore. You can even extend your function to other algebras (vector products, matrices, quaternions, etc.).

However, this does not meet your requirement.

+1


source







All Articles