Document directory
- About C ++ 14
- Types of automatically derived functions and Lambda return values
- Single-state Lambda and multi-state Lambda
- Lambda with template parameters
- Lambda whose function body is an expression
- Lambda capture expression
- Lambda parameter Extension
- Named Lambda
About C ++ 14 According to hurb Sutter's speech entitled "The Future of C ++", after the C ++ Standards Committee launched the C ++ 11 standard, there has not been much rest, and it has been invested in the formulation of the next two generations of standards (C ++ 14 and C ++ 17. The C ++ 14, which is expected to be launched next year, is positioned to revise and improve the current C ++ 11 standard. Despite the limited time, the next generation standard C ++ 14 still contains some notable new features. Judging from the existing proposals, the biggest new feature of C ++ 14 is the extension of Lambda and common functions. Below are some content that is likely to be added to the new standard. The status quo of the types of auto-derivation functions and Lambda return values: the types of Lambda return values can be automatically deduced by the compiler in two cases, without the need to specify them explicitly.
// If there is no return statement in the lambda function, the return value type is void [] () {STD: cout <"hello ";}; // explicitly specify the return value type as follows [] ()-> void {STD: cout <"hello ";}; // when a Lambda function contains only one return statement, the return value type is equivalent to the expression type [] (int x) {return x + 1 ;}; // The Return Statement expression x + 1 is of the int type. Therefore, the return value type is int. // The syntax for explicitly specifying the return value type is as follows: [] (int x) -> int {return x + 1 ;};
Defect: In most cases, the compiler does not have the ability to automatically derive Lambda and function return value types.
// For lambda, as long as there is a return value and the function body contains more than one statement, the type of its return value cannot be automatically deduced by the compiler, you must specify [] (int x)-> int {int y = x + 1; return y ;}; // for common functions or function templates, even if the function body contains only one statement // The type of its return value cannot be automatically deduced by the compiler, you must specify int F (int x) {return x + 1 ;} // for a common function or function template, even if the function uses the post-return type syntax // The type of its return value cannot be automatically deduced by the compiler. You must specify the template <typename t, typename u> auto MUL (const T & T, const U & U)-> decltype (T * u) {return T * U ;}
Countermeasure: In most cases, the compiler will be able to automatically derive Lambda and function return value types.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// The type of Lambda return value can be automatically deduced by the compiler without specifying [] (int x) {int y = x + 1; return y ;}; // specify the type of the normal function return value as auto // The Compiler automatically derives the type of the returned value auto F (int x) {return x + 1 ;} // specify the type of the function template return value as auto // The Compiler automatically derives the type template <typename T, typename u> auto MUL (const T & T, const U & U) {return T * U ;}Status Quo of single-State Lambda and multi-state lambda: Lambda in the current standard is a single-State (monomorphic) Lambda. That is, the type of the lambda parameter must be explicitly specified and cannot be automatically deduced by the compiler through context.
STD: for_each (begin (V), end (V), [] (decltype (* begin (V) x) {STD: cout <X ;}); // for_each algorithm function used to traverse the set // This algorithm requires that the third parameter is a function or function object that can receive the set element as a unique parameter. // This is the third parameter of the algorithm function. the unique parameter X of Lambda itself can only be the element type of set V // The Compiler does not automatically derive the function of the lambda parameter type according to the context // here the element x of set V it must be clearly stated that: decltype (* begin (v ))
Defect: There is no polymorphic Lambda or generic Lambda in the current standard. That is to say, lambda, which is automatically deduced by the compiler according to the context, is missing parameter types in the language.
Compare the C # code with the following functions:
Lst. foreach (x => {console. writeline ("{0}", x );}); // here, the list <t> foreach method is used to traverse the list // This method requires a delegate that can receive the element type of the set as a parameter // so here Lambda itself serves as the method parameter the type of the unique parameter X can only be the element type of the collection lst // because the C # compiler has the function of automatically deriving the lambda parameter type according to the context // here the type of the element x of the lst is not required
Countermeasure: add the new feature of generic Lambda (parameter types can be automatically derived by the compiler based on context.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Currently, the syntax form of generic Lambda remains controversial // syntax Form 1 (the standard committee discussed the initial proposal highly controversial and difficult to pass) STD :: for_each (begin (V), end (V), [] (x) {STD: cout <X ;}); // syntax Form 2 (feasible solution) STD:: for_each (begin (V), end (V), [] (& X) {STD: cout <X ;}); // syntax Form 3 (feasible solution) STD: for_each (begin (V), end (V), [] <> (& X) {STD: cout <X ;}); // syntax format 4 (improved proposal, which is highly controversial in the C ++ discussion group but is relatively easy to pass) STD: for_each (begin (V), end (V ), [] (Auto & X) {STD: cout <X ;});Lambda with template parameters: the current standard does not contain Lambda with template parameters.
// The following function template cannot be rewritten to the equivalent lambdatemplate <typename T, typename u> auto MUL (const T & T, const U & U) -> decltype (T * u) {return T * U ;}
Countermeasure: add the new Lambda feature with template parameters.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Lambdaauto Mul = [] <typename T, typename u> (const T & T, const U & U) {return T * U;} with template parameters ;}The function body is the lambda status of the expression: the lambda function body only has one form, even if a large arc code block is used.
// Even the simplest Lambda (the function contains only one return statement for the return expression), the function body must adopt the code block format auto F = [] (int x) {return x + 1 ;}; // nested Lambda [] (int x)-> function <int (INT)> {return [=] (INT y)-> function <int (INT)> {return [=] (int z) {return X + Y + z ;};};};
Defect: Compared with the C # language, the simplest Lambda statement is not concise.
Compare the C # code with the following functions:
// C # allows Lambda function bodies to use expressions. Func <int, int> = x => x + 1; // nested lambdafunc <int, func <int, func <int, int >>> G = x => Y => Z => X + Y + z;
Countermeasure: allow the simplest Lambda function bodies to adopt expressions.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Allows the lambda function body to use the expression format auto F = [] (int x) x + 1; // nested Lambda [] (int x) -> function <int (INT)> [=] (INT y)-> function <int (INT)> [=] (int z) X + Y + z;
Countermeasure: Considering the language consistency, if a common function and function template use Lambda syntax, the function body is also allowed to use expressions.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Use the extended Lambda syntax // The following function template <typename T, typename u> auto MUL (const T & T, const U & U) -> decltype (T * u) {return T * U;} // you can rewrite it to template <typename T, typename u> [] Mul (const T & T, const U & U) T * U;Lambda capture expression status quo: Through reference capture, Value capture, and other capture methods, Lambda functions can capture and use the local variables and class member variables defined in the periphery of Lambda.
// Reference capture int n = 1; [&] () {n ++; // n = 2 }(); // n = 2 // capture int n = 1; [=] () mutable {n ++; // n = 2 }(); // n = 1
Defect: The capture method is still insufficient. For example, mobile capture cannot be implemented.
// No mobile capture. Only STD: vector
Countermeasure: Introduce a capture expression to implement a common capture method.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Implement Mobile capture using the capture expression STD: vector Lambda parameter extension status and defects: Compared with common functions, Lambda function signatures do not have default parameters, nor can parameter names be omitted.
// The following functions cannot be rewritten as equivalent lambdaint F (INT x = 0) {return x + 1;} void g (INT/* unused */) {STD :: cout <"G ";}
Countermeasure: Allow Lambda function signatures to contain default parameters, and omit parameter names.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Default parameter and omitted parameter name auto F = [] (INT x = 0) {return x + 1 ;}; auto G = [] (INT/* unused */) {STD: cout <"G ";};Status Quo and defects of a named lambda: Lambda does not have a name and cannot be reloaded or recursive.
// Lambda can be named, but auto F1 = [] (int x) {STD: cout <"f int ";}; auto F2 = [] (Double X) {STD: cout <"f double" ;}; // Lambda cannot be directly recursive // auto factorial = [] (int x) -> int {return x = 0? 1: x * factorial (X-1) ;}; STD: function <int (INT)> factorial = [&] (int x) {return x = 0? 1: x * factorial (X-1 );};
Countermeasure: add the new feature named lambda.
Note: The following C ++ Code contains the expected new features of the language, which is not currently supported by the compiler.
// Named Lambda can overload [] F (int x) {STD: cout <"f int" ;}; [] F (Double X) {STD :: cout <"f double" ;}; // You can also recursively [] factorial (int x)-> int {return x = 0? 1: x * factorial (X-1 );};Related link: Generic (polymorphic) Lambda
Http://cpp-next.com/files/2012/09/N3418.pdf