How to limit the template parameter to only floating point type

Solution 1:

You can use std::floating_point concept to constrain the type T:

#include <concepts>

template<std::floating_point T>
constexpr auto func( const T num ) -> T {
  return num * 123;
}

Demo

Solution 2:

The below code works but I want to make it simpler:

You may combine abbreviated function templates and the std::floating_point concept for a condensed constrained function template definition:

constexpr auto func(std::floating_point auto num) {
  return num * 123;
}

Note that this does not include an explicitly specified trailing return type T as in your original approach, but that for the current definition the deduced return type will be decltype(num), which is either float or double (or impl-defined long double). As @Barry points out in the comments below, if you require a trailing return type, say for an overload with a ref- and cv-qualified function parameter, then the brevity gain of abbreviated templates is lost to the added cost of complex trailing return type.

// Contrived example: but if this was the design intent,
// then no: skip the abbreviated function template approach.
constexpr auto func(const std::floating_point auto& num) 
  -> std::remove_cvref_t<decltype(num)> { /* ... */ }

// ... and prefer
template<std::floating_point T>
constexpr auto func(const T& num) -> T  { /* ... */ }

// ... or (preferential)
template<std::floating_point T>
constexpr T func(const T& num) { /* ... */ }