简体   繁体   English

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

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

How to convert int to long inside/outside of lambda expression properly? 如何正确将int转换为lambda表达式的long内部/外部? How to check overflow of mathematics inside lambda properly? 如何正确检查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);

What's the best way to check for overflow after multiplying of integers inside/outside of lambda? 在lambda的内部/外部乘以整数后,检查溢出的最佳方法是什么?

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

Do I need to add TRT (trailing return type) -> long to lambda for proper conversion from int to long ? 我是否需要在Lambda中添加TRT(跟踪返回类型) -> long才能从int正确转换为long

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

Do I need to add static_cast to lambda for proper conversion from int to long : 我是否需要将static_cast添加到lambda才能从int正确转换为long

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

Or, may be, I need to combine this? 或者,可能是我需要结合起来吗?

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

Or, may be, I need to write the type of lambda? 或者,也许是,我需要编写lambda的类型?

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

First part of your question is a duplicate (although C question, C++ doesn't differ, and there are duplicates of including C++). 问题的第一部分是重复的 (尽管C问题,C ++没什么不同,并且包含C ++的重复)。 Most important point: You cannot detect signed integer overflow after multiplication, as it already caused undefined behaviour – unless you do calculation in next larger data type; 最重要的一点是:您不能乘法之后检测到有符号整数溢出,因为它已经引起了不确定的行为–除非您在下一个更大的数据类型中进行计算;否则,请执行下列操作: be aware, though, that int and long on many (but not all!) platforms (including Windows on modern PC hardware) have the same size, so switching to long is not a guarantee to avoid overflow! 但是请注意,在很多(但不是全部!)平台(包括现代PC硬件上的Windows)上, intlong具有相同的大小,因此切换到long并不是避免溢出的保证! If you want to be safe, use the data types from <cstdint> header (such as int16_t , int32_t , int64_t ). 为了安全起见,请使用<cstdint>标头中的数据类型(例如int16_tint32_tint64_t )。 If you have some specific reason to insist on int, you'd have to invest some extra work to get guaranteed next larger type. 如果您出于某些特殊原因坚持使用int,则必须投入一些额外的工作来保证有更大的下一个类型。 This question is not specific to lambdas, though, but concerns any multiplication (and even addition). 但是,此问题并非特定于lambda,而是涉及任何乘法(甚至加法)。

To guarantee a specific return type (again, the question is not specific to lambdas, but to any automatic deduction of type, be it a return type or an auto variable), both aproaches are valuable (explicit trailing return type and a cast), however, as presented, the results do differ! 为了保证特定的返回类型(同样,问题不是特定于lambda,而是针对类型的任何自动推导,无论是返回类型还是自动变量),这两种方法都是很有价值的(显式尾随返回类型和强制类型转换),但是,如前所述,结果确实有所不同!

Just applying the trailing return type is equivalent to having 仅应用尾随返回类型等同于具有

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

Note that the cast is placed around the entire calculation, ie the cast is done after the calculation, which still is done in int . 请注意,强制转换围绕整个计算进行,即强制转换是计算之后完成的,仍然在int完成。 If size of int and long do differ, the result can differ from your own casting variant: 如果int和long的大小确实不同,则结果可能与您自己的转换变量不同:

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

as this enforces already the multiplication being done in long (but not the subtractions! – to enforce even these, too, you'd need to cast i ). 因为这已经强制执行了long的乘法运算(但不是强制执行减法!–要也强制执行乘法运算,您还需要强制转换i )。 This cast is entirely sufficient to get the desired return type; 这种转换完全足以获得所需的返回类型。 an explicit trailing return type (in addition) shows more clearly, though, what the lambda actually returns without having to peek into the implementation. 但是,显式的尾随返回类型(另外)会更清楚地显示lambda实际返回的内容,而不必查看实现。 This is especially useful if you have a more complex lambda, and it can help to guarantee a consistent return type if you have multiple exit points. 如果您具有更复杂的lambda,这将特别有用;如果您有多个退出点,则可以帮助确保返回类型的一致性。

暂无
暂无

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

相关问题 关于C ++中尾随返回类型的问题17 - Question about trailing return type in C++17 Class type undefined in static member lambda function in C++17 - Class type undefined in static member lambda function in C++17 C++17 推断基于 lambda 的访问者的返回类型 - C++17 Infer return type of lambda based visitor C ++强制转换显式类型转换(C样式转换)和static_cast的多种解释 - C++ cast notation of explicit type conversion (C-style cast) and multiple interpretations of static_cast 转换为枚举类型需要显式强制转换(static_cast,C样式强制转换或函数样式强制转换)枚举 - Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast) enum 转换为枚举类型需要显式强制转换(static_cast,C样式强制转换或函数样式强制转换) - Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast) 将类型转换包装在static_cast中会不会很痛? - Can wrapping a type conversion in a static_cast ever hurt? C ++ 17 lambda捕获具有宽松的类型要求 - C++17 lambda captures with relaxed type requirements 我可以使用C ++ 17 captureless lambda constexpr转换运算符的结果作为函数指针模板非类型参数吗? - Can I use the result of a C++17 captureless lambda constexpr conversion operator as a function pointer template non-type argument? constexpr static 的未定义行为从 int 强制转换为具有非固定基础类型的作用域枚举在 C++17 中编译 - Undefined behavior of constexpr static cast from int to scoped enum with non-fixed underlying type compiles in C++17
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM