比较模板中的不同类型

时间:2014-10-08 07:11:34

标签: c++ templates

我想创建一个函数来检查参数是否超出范围。

我写了这个:

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);
    }
}

但是,当我这样做时

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

我收到警告:

warning: comparison between signed and unsigned integer expressions

如何制作一个安全地处理所有类型的功能?

4 个答案:

答案 0 :(得分:1)

正如@Borisbn所说,你可以这样做:

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);
    }
}

修改

我认为你可以这样做:

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);
}

答案 1 :(得分:1)

使用一个在符号不匹配的情况下返回正确结果的函数,而不是使用内置operator <

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;
}

你仍然会收到警告,所以你可能还想要一些#pragma GCC diagnostic push; ignored; pop

答案 2 :(得分:1)

作为o11c和Ajay的答案的组合,您可以使用此比较功能,它不会产生任何警告:

template<typename A, typename B>
bool lt(A a, B b) {
    if (a < 0 && b >= 0)
        return true;
    if (a >= 0 && b < 0)
        return false;
    using TYPE = decltype(a + b);
    return static_cast<TYPE>(a) < static_cast<TYPE>(b);
}

它适用于有符号和无符号数字类型的任意组合。

Demo

答案 3 :(得分:0)

你需要推断出三者中最大的类型。您可以使用这种方法:

template<typename X, typename Y, typename Z >
void checkParameter(X val, Y lower, Z upper)
{
    using TYPE = decltype(val + lower + upper);
    if (((TYPE) val > (TYPE) upper) || ((TYPE) val < (TYPE)lower))
    { 
        ASSERT(false);
    }
}

您的编译器应该支持decltype以及此using构造。