Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test for both std::is_integral and std::is_signed?

I have a function but I want to split it into two functions, one for returning signed integers and one for unsigned integers. It looks like std::is_signed is not strictly for integers so I thought if I could a template test for something like std::is_integral<T>::value && std::is_signed<T>::value but that doesn't work. Right now I have the signed test as an if statement:

template<typename T>
typename std::enable_if
<
    std::is_integral<T>::value,
    T
>::type
foo()
{
    if( std::is_signed<T>::value )
    {
        //signed
    }
    else
    {
        //unsigned
    }
}


EDIT. I'm using Visual Studio 2010. Actually it looks like what's happening is Visual Studio will not accept two templates, one with std::is_integral<T>::value && std::is_signed<T>::value and one with std::is_integral<T>::value && std::is_unsigned<T>::value. It tells me function template has already been defined. Am I doing this wrong and is there a more standard compliant way to have two functions, one that is for returning unsigned integral, and one for signed integral?

like image 928
loop Avatar asked Mar 24 '14 06:03

loop


2 Answers

Oops... just seen your edit... so you're trying to create alternative code... this work in the ideone demo here:

template <typename T>
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value,
                        int>::type f();


template <typename T>
typename std::enable_if<std::is_integral<T>::value && !std::is_signed<T>::value,
                        unsigned>::type f();
...

Do you want to give that a spin with VS2010 and report the outcome?

Alternatively, you could do this with std::conditional combines with the if statement you've got in your question's code - the unused code will be optimised away at compile time).

like image 142
Tony Delroy Avatar answered Oct 30 '22 13:10

Tony Delroy


I might use tag dispatching:

namespace Detail
{
    template <typename T>
    T fooHelper(std::true_type /*isSignedTag*/)
    {
        //signed
    }
    template <typename T>
    T fooHelper(std::false_type /*isSignedTag*/)
    {
        //unsigned
    }
}
template <typename T>
T foo()
{
    return Detail::fooHelper<T>(typename std::is_signed<T>::type());
}
like image 20
Oktalist Avatar answered Oct 30 '22 13:10

Oktalist