繁体   English   中英

C ++ 17中的Lambda表达式:尾随返回类型与static_cast进行类型转换

[英]Lambda expression in C++17: trailing return type vs static_cast for type conversion

如何正确将int转换为lambda表达式的long内部/外部? 如何正确检查lambda内部的数学溢出?

int n = 12; // input parameter from std::cin
int a = 23; // input parameter from std::cin
int i = 34; // input parameter from std::cin
auto f = [n, a] (int i) { return a * (n - (i - 1)); };
auto result = f(i);

在lambda的内部/外部乘以整数后,检查溢出的最佳方法是什么?

auto result = f(i);
if ((result > std::numeric_limits<int>::max()) || (result < std::numeric_limits<int>::min())) {
    cout << "overflow was detected" << endl;
}

我是否需要在Lambda中添加TRT(跟踪返回类型) -> long才能从int正确转换为long

auto f = [n, a] (int i) -> long { return a * (n - (i - 1)); };

我是否需要将static_cast添加到lambda才能从int正确转换为long

auto f = [n, a] (int i) { return static_cast<long>(a) * (n - (i - 1)); };

或者,可能是我需要结合起来吗?

auto f = [n, a] (int i) -> long { return static_cast<long>(a) * (n - (i - 1)); };

或者,也许是,我需要编写lambda的类型?

std::function< long( int ) > f = [n, a] (int i) { return a * (n - (i - 1)); };

问题的第一部分是重复的 (尽管C问题,C ++没什么不同,并且包含C ++的重复)。 最重要的一点是:您不能乘法之后检测到有符号整数溢出,因为它已经引起了不确定的行为–除非您在下一个更大的数据类型中进行计算;否则,请执行下列操作: 但是请注意,在很多(但不是全部!)平台(包括现代PC硬件上的Windows)上, intlong具有相同的大小,因此切换到long并不是避免溢出的保证! 为了安全起见,请使用<cstdint>标头中的数据类型(例如int16_tint32_tint64_t )。 如果您出于某些特殊原因坚持使用int,则必须投入一些额外的工作来保证有更大的下一个类型。 但是,此问题并非特定于lambda,而是涉及任何乘法(甚至加法)。

为了保证特定的返回类型(同样,问题不是特定于lambda,而是针对类型的任何自动推导,无论是返回类型还是自动变量),这两种方法都是很有价值的(显式尾随返回类型和强制类型转换),但是,如前所述,结果确实有所不同!

仅应用尾随返回类型等同于具有

[n, a] (int i) { return static_cast<long>(a * (n - (i - 1))); };
//                                         ^               ^

请注意,强制转换围绕整个计算进行,即强制转换是计算之后完成的,仍然在int完成。 如果int和long的大小确实不同,则结果可能与您自己的转换变量不同:

[n, a] (int i) { return static_cast<long>(a) * (n - (i - 1)); };

因为这已经强制执行了long的乘法运算(但不是强制执行减法!–要也强制执行乘法运算,您还需要强制转换i )。 这种转换完全足以获得所需的返回类型。 但是,显式的尾随返回类型(另外)会更清楚地显示lambda实际返回的内容,而不必查看实现。 如果您具有更复杂的lambda,这将特别有用;如果您有多个退出点,则可以帮助确保返回类型的一致性。

暂无
暂无

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

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