Lambda expressions as parameters of a class template in C ++ 14

The question of Lambda expressions as parameters of a class template asks a question about the possibility of using lambda expressions as parameters of a class template.

The answer to the question was no. However, it was about C ++ 11.

Is the situation changed in the new standard, C ++ 14?

+6
source share
2 answers

No situation in C ++ 14 changed at all, and in fact, the language in section 5.1.2 Lambda expressions, paragraph 2, were compressed:

A lambda expression must not appear in an unpublished operand (clause 5).

in

[...] A lambda expression must not appear in an unpublished operand (Clause 5), in a template, in an alias declaration, in a typedef declaration or in a function or function declaration template outside its function body and default arguments. [Note The goal is to prevent lambda from appearing in the signature. -end note] [...]

Defect report 1607. Lambdas in the template parameters leads to this change.

A defect report obliquely refers only to the justification for rejecting this, but we can find a very detailed explanation of why this is prohibited in The rationale for lambda expressions is not allowed in unreasonable contexts . The reasons are as follows:

  • Lambda expressions that do not have a unique type
  • Problems with compiler implementation:
    • Like the unusual SFINAE extension
    • A possible requirement is to call mangle the whole body of a lambda.

Given the validity of this limitation, it seems unlikely.

+2
source

Is the situation changed in the new standard, C ++ 14?

The Lambda expression is still not displayed in the unvalued operand - the same quote as in the Xeo Post also exists in the latest publicly available N3797 project, in exactly the same place.

However, each type of closure has a remote default constructor (N3797, §5.1.2 / 20):

The closure type associated with the lambda expression is deleted (8.4.3) and the delete copy delete statement.

So, for portabiliby and standard compliance (and probably for working code on reasonable compilers) you will need to pass the closure object to the constructor of the instance class for copying. But in order to pass a closure object of the same type as the template argument of this specialization , you must define it anyway:

 using my_map_type = map<int, int, decltype([] (auto&& lhs, auto&& rhs) {return lhs < rhs*4;})>; // Assuming the above compiles my_map_type m( [] (auto&& lhs, auto&& rhs) {return lhs < rhs*4;} ); // Different closure type - compiler error! What do you copy from!? 

There is no legal way to create a single object such as closing the first lambda. Therefore, even if the specified rule must be deleted, you cannot create one instance of my_map_type . Similar problems arise with other scenarios such as closure as a pattern.

+1
source

Source: https://habr.com/ru/post/976172/


All Articles