繁体   English   中英

是否有“安全”的 static_cast 替代方案?

[英]Is there a "safe" static_cast alternative?

在 C++11/14 或实现此功能的库中是否有static_cast的“安全”替代方案?

通过“安全”我的意思是演员阵容应该只允许不失去精度的演员阵容。 因此,只有当数字适合int32_t时才允许从int64_t转换为int32_t ,否则会报告错误。

gsl::narrow

窄 // narrow<T>(x)static_cast<T>(x)如果static_cast<T>(x) == x或它抛出narrowing_error

你已经颠倒了用例。

static_cast (以及其他 c++ 风格的强制转换)的预期用途是表明程序员的意图。 当你写auto value = static_cast<int32_t>(value_64); ,您是在说“是的,我非常*打算*在执行此任务时降低此值,可能会截断它” 结果,在正常情况下可能倾向于抱怨这种转换的编译器(例如,如果您编写了int32_t value = value_64; )反而观察到“好吧,程序员告诉我这是他们想要的;他们为什么要骗我?” 并将默默地编译代码。

如果您希望 C++ 代码在不安全转换时发出警告或抛出错误,则需要明确使用static_castconst_castreinterpret_cast ,并让编译器完成其工作。 编译器具有更改警告处理方式的标志(将int64_t向下转换为int32_t通常只会导致警告),因此请确保您使用正确的标志来强制将警告视为错误。

假设问题是关于潜在有损转换的编译时检测......

这里还没有提到的一个简单工具是列表初始化不允许缩小,因此您可以编写:

void g(int64_t n)
{
    int32_t x{n};   // error, narrowing

    int32_t g;
    g = {n};        // error, narrowing
}

注意。 某些处于默认模式的编译器可能会显示“警告”并继续编译此格式错误的代码,通常您可以通过编译标志配置此行为。

您可以使用 sfinae 创建自己的。 下面是一个例子:

template <typename T, typename U>
typename std::enable_if<sizeof(T) >= sizeof(U),T>::type 
safe_static_cast(U&& val)
{
    return static_cast<T>(val);
}

int main()
{
    int32_t y = 2;
    std::cout << safe_static_cast<int32_t>(y) << std::endl;
    std::cout << safe_static_cast<int16_t>(y) << std::endl; // compile error
}

仅当您投射到的大小 >= 源大小时才会编译。

在这里试试

您可以将numeric_limits用于其他类型和type_traits使这进一步复杂化。

请注意,我的解决方案是一个编译时解决方案,因为您询问了static_cast ,这里的 static 是指“在编译时确定”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM