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

标签 c++ types error-handling type-conversion numeric-limits

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

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

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

检查

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

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

例如,999998989898988989999 会转换为 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 << "error\n";
            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 << "error\n";
            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 << "error\n";
            return;
        }
        func_impl(k);
    }
    
private:
    void func_impl(K const& k) 
    {
        std::cout << "normal\n";
    }
};


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

输出:

normal

normal

normal

error

error

error

error

normal

LIVE

编辑

正如@BaumMitAugen 指出的,boost::numeric_cast在我的 func 实现中,这可能是手动 if 的更好替代方案 - 如果发生下溢或溢出,它将抛出异常,并且您将避免大量的样板代码最新编辑的代码版本(a)可以工作并且(b)避免签名/未签名的比较警告。

关于c++ - 如何将大于 std::numeric_limits<fundamental_type>::max() 的值传递给函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33842775/

相关文章:

php - 将字符串视为字符数组是否会返回 “Uninitialized string offset”通知?

python - Pybind11 : "ImportError: DLL not found" when trying to import *. Python解释器中的pyd

c++ - OpenMP 和#pragma omp atomic

c++ - std::vector of objects/pointers/smart pointers to pass objects (bus error: 10)?

Java - 使用 Comparable 的静态泛型类型

haskell - 如何以类型编码可能的状态转换?

c++ - Qt:如何通过外部程序打开文件, "open with..."对话框

Java类型参数与参数

asp.net-mvc-3 - RedirectToAction retcode 错误处理最佳实践

php - 在 PHP 和 mysql 中调试的最佳方法