Home c++ Output Lambda type expression with default parameter

Output Lambda type expression with default parameter

Author

Date

Category

Without using the -wpedantic Compiler with C++ 11, allows you to use the default value in lambda expressions.

For such an expression, you can use the STD :: FUNCTION type with the types of all parameters, including those that are specified by default.

However, using automatic type output indicating the AUTO keyword, the lambda expression receives a specific type, for example, main () :: & lt; lambda (int) & gt; , where the values ​​are in parentheses – Types of parameters transmitted to this expression. And these values ​​are always indicated regardless of whether they have the default value (which is generally logical).

below give an example code.

# include & lt; functional & gt;
#Include & lt; iostream & gt;
Void F1 (STD :: FUNCTION & LT; int () & gt; lambda)
{
  if (lambda)
  {
    STD :: COUT & LT; & LT; lambda () & lt; & lt; STD :: ENDL;
  }
}
Void F2 (STD :: FUNCTION & LT; INT (INT) & GT; LAMBDA)
{
  if (lambda)
  {
    STD :: COUT & LT; & LT; lambda (1) & lt; & lt; STD :: ENDL;
  }
}
INT MAIN ()
{
  AUTO LAMBDA1 = [] (int a = 3) - & gt; int.
  {
    RETURN A;
  };
  F1 (lambda1);
  F2 (lambda1);
  STD :: FUNCTION & LT; INT () & GT; lambda2 = [] ()
  {
    Return 1;
  };
  STD :: FUNCTION & LT; INT (INT) & GT; lambda3 = [] (int A)
  {
    RETURN A;
  };
  F1 (lambda2);
  // F2 (lambda2); // Obvious the inconsistency of types
  // F1 (lambda3); // Obvious the inconsistency of types
  F2 (lambda3);
}

In the code example, the type main () :: & lt; lambda (int) & gt; is provided to STD :: FUNCTION & LT; INT () & GT; . I do not have enough knowledge to understand why the compiler does not swear on the inconsistency of the types. I ask for help in explanation.

and related questions.

Can I explicitly specify a type similar to what is displayed automatically?

Can I specify the compiler so that it forbade such a type of type?


Answer 1, Authority 100%

The type of closure object, generated by the lambda expression, does not depend on the lambda parameters and is not determined by them. The presence or absence of arguments by default does not play any role here. Each lambda expression generates a new unique type – that’s all you need to know about the type of closure object. Even if two lambda expressions are completely identical, they will still receive unique types that are not connected with each other. The fact that in your example in the domestic name of this type you saw some hint of the parameter list – no more than the cosmetic feature of the implementation you use. At the same time, a text description of the type of facility object, which you see in the compiler messages is not an exhaustive description of the actual type.

For example, in response to

auto f1 = [] () {};
AUTO F2 = [] () {};
& amp; f1 == & amp; f2;

You will receive from the GCC diagnostic message of the type

error: comparison between distinct pointer type
 'main () :: & lt; lambda () & gt; *' and 'main () :: & lt; lambda () & gt; *' Lacks a Cast

As you can see, the descriptions of types in quotes are completely identical. Nevertheless, these are different, in no way connected with each other.

So when working with lambda expressions, no speech about “compliant types” cannot be at all: all types of closure objects are unique and never correspond to anything.

why the compiler does not swear to the inconsistency of types

Class STD :: FUNCTION & LT; & GT; built on the principles of Type Erasure, i.e. In fact, it is a more narrowly specialized analogue STD :: Any . The designer of this class is template (see number 5 here ) – There is no check in it at all and there can be no test “Types” at the level of the language of language types. At the level of the language type system, this designer can take absolutely any types.

And any checks are hung on this constructor already at the level of library implementation, through the technique like SFINAE. When initializing the type STD :: FUNCTION & LT; F & GT; SF = F; Checking CALLABLE : The f object should be CALLABLE as a function like F . Check this requirement and works in your example.

For example, the Lambda1 closure object is CALLABLE and how int () and how int (int) . Therefore, you can use it and to initialize STD :: FUNCTION & LT; INT () & GT; , and for initialization Std :: Function & LT; int (int) & gt; .

Can I explicitly specify a type similar to what is displayed automatically?

clearly – no. The type of closure object is determined by the implementation and syntax for its explicit instruction does not exist. You can “specify” it only implicitly after it has already taken out – through the use of decltype to the already existing closure object

auto f1 = [] () {};
decltype (f1) f2 = f1;

Can I specify the compiler so that it forbade such a type of type?

Compiler here has nothing to do with it. You are dealing with pure Library functionality: implementation STD :: FUNCTION & LT; & GT; . While you use the class STD :: FUNCTION & LT; & GT; , it will behave as the language specification requires.


Answer 2, Authority 50%

Ban to specify default parameters in lambda expressions was recognized as a defect, and eliminated in subsequent variants of the standard . So compilers belong to such actions through the fingers. The type of lambda expression is anonymous and therefore clearly turn to it, or somehow it is not possible to specify it in a different way. Std :: Function There is an implicit template designer that can take suitable lambda expression objects, so that nothing can be done here.


Answer 3, Authority 12%

  1. Compiler does not swear, because lambda_function can be stored in
    Object STD :: FUNCTION
  2. can not explicitly specify type_ this type depends on the implementation and its name
    Also known only compiler.
  3. no type of types is satisfied (see clause number 1), therefore
    Specify not to do what is not done, you can not

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions