Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing different types in template

Tags:

c++

templates

I want to create a function which will check if parameters are out of range.

I have written this:

template<typename X,typename Y,typename Z >
void checkParameter( X val, Y lower, Z upper)
{
    if( ( val > upper) || ( val < lower) )
    {
        log("checkParameter, val = % , lower= % , upper= %  \n", val,
                          lower,upper );
        ASSERT(false);
    }
}

However, when I do this

uint32_t var = 5000;
checkParameter( var, 0, 262143);

I get the warning:

warning: comparison between signed and unsigned integer expressions

How can I make a function which safely will handle all types?

like image 945
user1876942 Avatar asked Oct 20 '22 00:10

user1876942


2 Answers

Instead of using builtin operator <, use a function that returns the correct result in case of sign mismatches

template<class A, class B>
bool lt(A a, B b)
{
    if (a < 0 && b >= 0)
        return true;
    if (a >= 0 && b < 0)
        return false;
    return a < b;
}

You'll still get warnings, so you'll probably also want some #pragma GCC diagnostic push; ignored; pop around it.

like image 157
o11c Avatar answered Oct 22 '22 15:10

o11c


As @Borisbn said you could do this like this:

template<typename type >
void checkParameter( type val, type lower, type upper)
{

    if( ( val > upper) || ( val < lower) )
    {
        log("checkParameter, val = % , lower= % , upper= %  \n", val,
                          lower,upper );
        ASSERT(false);
    }
}

EDIT

I think you could do this like this:

template<bool A, bool B, bool C>
struct test {
  template < typename T1, typename T2, typename T3>
  void parameters (T1, T2, T3) { /* Mismatching types */ }
};

template<>
struct test<true, true, true> { // all parameters will be signed                                                                       
  template < typename T1, typename T2, typename T3>
  void parameters (T1 a, T2 b, T3 c) {
    /* do your test here */
  }
};


template<>
struct test<false, false, false> { //all parameters will be unsigned                                                                   
  template < typename T1, typename T2, typename T3>
  void parameters (T1 a, T2 b, T3 c) {
    /* do your test here */
  }
};

template < typename T1, typename T2, typename T3>
void    testParameters(T1 a, T2 b, T3 c) {
  test<std::is_signed<T1>::value, std::is_signed<T2>::value, std::is_signed<T3>::value>::parameters(a,b,c);
}
like image 35
CollioTV Avatar answered Oct 22 '22 14:10

CollioTV