如何将大于 std::numeric_limits<fundamental_type>::max() 的值传递给函数?

How to pass values greater than std::numeric_limits<fundamental_type>::max() to a function?

本文关键字:max 值传 函数 gt type numeric 大于 limits fundamental lt std      更新时间:2023-10-16

我正在编写一个函数void func(K const& val),它是模板类的一部分。

假设我将类对象定义为foo<unsigned short int> f;,然后将函数调用为f.func(999999);

发生的情况是值999999被转换为其他值,因为它本身超出了范围。如何防止这种情况发生?代码中是否有编译器标志或其他方式可以防止这种情况发生?

检查

if(val > std::numeric_limits<K>::max())

func内部的值没有帮助,因为在传递该值时,该值已经转换为数值限制内的值。

例如,99999 898989899999转换为11823

如何将大于std::numeric_limits::max()的值传递给函数?

附言:我正在使用gcc(带有-std=c++11)编译

假设类foo的定义类似于:

template<typename K>
class foo {
public:
    void func(K const& k) {}
};

您可以自己制作func模板,并在调用实际实现之前检查限制:

#include <iostream>
#include <limits>
template<typename K>
class foo {
public:
    template<typename T>
    std::enable_if_t<std::is_signed<T>::value && !std::is_signed<K>::value> func(T const& t) 
    {
        if (t < 0 || static_cast<std::make_unsigned_t<T>>(t) > std::numeric_limits<K>::max()) {
            std::cout << "errorn";
            return;
        }
        
        func_impl(t);
    }
    
    template<typename T>
    std::enable_if_t<!std::is_signed<T>::value && std::is_signed<K>::value> func(T const& t) 
    {
        if (t > static_cast<std::make_unsigned_t<K>>(std::numeric_limits<K>::max())) {
            std::cout << "errorn";
            return;
        }
        
        func_impl(t);
    }
    
    template<typename T>
    std::enable_if_t<std::is_signed<T>::value == std::is_signed<K>::value> func(T const& k)
    {
        if (k < std::numeric_limits<K>::min() || k > std::numeric_limits<K>::max()) {
            std::cout << "errorn";
            return;
        }
        func_impl(k);
    }
    
private:
    void func_impl(K const& k) 
    {
        std::cout << "normaln";
    }
};

int main()
{
    foo<char>().func(127);
    foo<char>().func(127u);
    foo<char>().func(-128);
    foo<char>().func(128);
    foo<char>().func(128u);
    foo<char>().func(-129);
    foo<unsigned>().func(-1);
    foo<int>().func(1u);
}

输出:

正常

正常

正常

错误

错误

错误

错误

正常

实时

编辑

正如@BaumMitAugen所指出的,在我的func实现中,boost::numeric_cast可能是手动if的更好替代方案——如果发生下溢或上溢,它将引发异常,并且您将避免许多最新编辑版本的代码样板,这些代码(a)有效,(b)避免有符号/无符号的比较警告。