Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::numeric_limits as a Condition

Is there a way that I can use std::numeric_limits<T>::is_integer and std::numeric_limits<T>::is_specialized to change template behavior?

For example can I do this:

template < typename T >
void foo( const T& bar )
{
    if( std::numeric_limits< T >::is_integer )
    {
        isInt( bar );
    }
    else if( std::numeric_limits< T >::is_specialized )
    {
        isFloat( bar );
    }
    else
    {
        isString( bar );
    }
}
like image 574
Jonathan Mee Avatar asked Feb 07 '26 17:02

Jonathan Mee


1 Answers

What you have is currently valid. However, you should prefer to use SFINAE and <type_traits> instead since it would dispatch to a different function based on the type rather than rely on a branch condition (which may or may not be optimized away).

You can use std::enable_if to do the following:

template<typename T, 
         typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& t) {
    isInt(t);
}

template<typename T, 
         typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
void foo(const T& t) {
    isFloat(t);
}

template<typename T, 
         typename std::enable_if<!std::is_integral<T>::value && 
                                 !std::is_floating_point<T>::value, int>::type = 0>
void foo(const T& t) {
    isString(t);
}

Live Demo

The reason that the second parameter for enable_if is set to int is to save us some typing. If the int is left out then we'd have to do typename = typename std::enable_if<std::is_integral<T>::value>::type instead of just setting it to 0 which would save us a couple of characters to type. They're equivalent for all intents and purposes.

like image 115
Rapptz Avatar answered Feb 09 '26 05:02

Rapptz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!