Is there a way to limit a template parameter T
to a specific type or category?
The below code works but I want to make it simpler:
#include <iostream>
#include <type_traits>
template <typename T>
constexpr auto func( const T num ) -> T
{
static_assert( std::is_floating_point_v<T>, "Floating point required." );
return num * 123;
}
int main( )
{
std::cout << func( 4345.9 ) << ' ' // should be ok
<< func( 3 ) << ' ' // should not compile
<< func( 55.0f ) << '\n'; // should be ok
}
I want to get rid of the static_assert
and write something like this:
template < std::is_floating_point_v<T> >
constexpr auto func( const T num ) -> T
{
return num * 123;
}
Any suggestions? Anything from type_traits or maybe concepts would be better.
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
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) { /* ... */ }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With