如何针对签名和/或未签名参数(std :: is_unsigned)专门化模板函数

时间:2018-10-12 20:28:31

标签: c++ templates

我写了一个简短的函数来计算一个值的位数(整数部分)。

template <typename T>
static size_t digits(T num) {
    auto is_fraction_of_one = [](T num) {
        return (num > 0 && num < 1) || (num > -1 && num < 0);
    };
    if (num == 0 || is_fraction_of_one(num))
        return 1;

    return std::is_unsigned_v<T> ? \
            static_cast<size_t>(std::log10(num)) + size_t(1) : \
            static_cast<size_t>(std::log10(num < 0 ? -num : num)) + size_t(1);
}

如果0 <= abs(num) < 1返回1,否则它将通过std::log10(num)+1计算位数。

代码按原样工作,但是编译器(Windows VC ++)警告:

  

警告C4146:一元减运算符应用于无符号类型,结果   仍未签名

这很公平,因为它不认识到最后一行中的-num部分仅在签名T时执行。

如果我想重写代码以防止出现此警告,我该怎么办?

由于std::is_unsigned_vconstexpr,我觉得我应该能够将代码分成两个单独的模板函数:一个用于签署T时,另一个用于签署时。不。但是我不知道该怎么做。


注意:

我意识到我可以缩短代码,并通过将num强制转换为double来避免警告(因为std::log10仍然会在没有模板arg的情况下执行此操作):

template <typename T>
static size_t digits(T num) {
    double dnum = std::fabs(static_cast<double>(num));
    if (dnum >= 0.0 && dnum < 10.0)
        return 1;
    return static_cast<size_t>(std::log10(dnum)) + size_t(1);
}

但是我要问的问题主要是出于我自己的学历。另外,我确实还有一些其他功能,它们可能会从该解决方案中获得更适当的收益(无论如何)。

0 个答案:

没有答案