|
602 | 602 | \terminal{[} lambda-capture\opt{} \terminal{]}
|
603 | 603 | \end{bnf}
|
604 | 604 |
|
605 |
| -\begin{bnf} |
606 |
| -\nontermdef{lambda-capture}\br |
607 |
| - capture-default\br |
608 |
| - capture-list\br |
609 |
| - capture-default \terminal{,} capture-list |
610 |
| -\end{bnf} |
611 |
| - |
612 |
| -\begin{bnf} |
613 |
| -\nontermdef{capture-default}\br |
614 |
| - \terminal{\&}\br |
615 |
| - \terminal{=} |
616 |
| -\end{bnf} |
617 |
| - |
618 |
| -\begin{bnf} |
619 |
| -\nontermdef{capture-list}\br |
620 |
| - capture \terminal{...\opt}\br |
621 |
| - capture-list \terminal{,} capture \terminal{...\opt} |
622 |
| -\end{bnf} |
623 |
| - |
624 |
| -\begin{bnf} |
625 |
| -\nontermdef{capture}\br |
626 |
| - simple-capture\br |
627 |
| - init-capture |
628 |
| -\end{bnf} |
629 |
| - |
630 |
| -\begin{bnf} |
631 |
| -\nontermdef{simple-capture}\br |
632 |
| - identifier\br |
633 |
| - \terminal{\&} identifier\br |
634 |
| - \terminal{this}\br |
635 |
| - \terminal{* this} |
636 |
| -\end{bnf} |
637 |
| - |
638 |
| -\begin{bnf} |
639 |
| -\nontermdef{init-capture}\br |
640 |
| - identifier initializer\br |
641 |
| - \terminal{\&} identifier initializer |
642 |
| -\end{bnf} |
643 |
| - |
644 | 605 | \begin{bnf}
|
645 | 606 | \nontermdef{lambda-declarator}\br
|
646 | 607 | \terminal{(} parameter-declaration-clause \terminal{)} decl-specifier-seq\opt\br
|
|
659 | 620 | \end{codeblock}
|
660 | 621 | \end{example}
|
661 | 622 |
|
662 |
| -\pnum |
663 |
| -In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator}, |
664 |
| -each \grammarterm{decl-specifier} |
665 |
| -shall either be \tcode{mutable} or \tcode{constexpr}. |
666 |
| -\begin{example} |
667 |
| -\begin{codeblock} |
668 |
| -auto monoid = [](auto v) { return [=] { return v; }; }; |
669 |
| -auto add = [](auto m1) constexpr { |
670 |
| - auto ret = m1(); |
671 |
| - return [=](auto m2) mutable { |
672 |
| - auto m1val = m1(); |
673 |
| - auto plus = [=](auto m2val) mutable constexpr |
674 |
| - { return m1val += m2val; }; |
675 |
| - ret = plus(m2()); |
676 |
| - return monoid(ret); |
677 |
| - }; |
678 |
| -}; |
679 |
| -constexpr auto zero = monoid(0); |
680 |
| -constexpr auto one = monoid(1); |
681 |
| -static_assert(add(one)(zero)() == one()); // OK |
682 |
| - |
683 |
| -// Since \tcode{two} below is not declared \tcode{constexpr}, an evaluation of its \tcode{constexpr} member function call operator |
684 |
| -// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture) |
685 |
| -// in a constant expression. |
686 |
| -auto two = monoid(2); |
687 |
| -assert(two() == 2); // OK, not a constant expression. |
688 |
| -static_assert(add(one)(one)() == two()); // ill-formed: \tcode{two()} is not a constant expression |
689 |
| -static_assert(add(one)(one)() == monoid(2)()); // OK |
690 |
| -\end{codeblock} |
691 |
| -\end{example} |
692 |
| - |
693 | 623 | \pnum
|
694 | 624 | A \grammarterm{lambda-expression} is a prvalue
|
695 | 625 | whose result object is called the \defn{closure object}. A
|
|
706 | 636 | object~(\ref{function.objects}).\end{note}
|
707 | 637 |
|
708 | 638 | \pnum
|
709 |
| -The type of the \grammarterm{lambda-expression} (which is also the type of the |
710 |
| -closure object) is a unique, unnamed non-union class type |
711 |
| ---- called the \defn{closure type} --- |
| 639 | +If a \grammarterm{lambda-expression} does not include a |
| 640 | +\grammarterm{lambda-declarator}, it is as if the \grammarterm{lambda-declarator} were |
| 641 | +\tcode{()}. |
| 642 | +The lambda return type is \tcode{auto}, which is replaced by the |
| 643 | +type specified by the |
| 644 | +\grammarterm{trailing-return-type} if provided and/or deduced from |
| 645 | +\tcode{return} statements as described in~\ref{dcl.spec.auto}. |
| 646 | +\begin{example} |
| 647 | +\begin{codeblock} |
| 648 | +auto x1 = [](int i){ return i; }; // OK: return type is \tcode{int} |
| 649 | +auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} |
| 650 | +int j; |
| 651 | +auto x3 = []()->auto&& { return j; }; // OK: return type is \tcode{int\&} |
| 652 | +\end{codeblock} |
| 653 | +\end{example} |
| 654 | + |
| 655 | +\rSec3[expr.prim.lambda.closure]{Closure types}% |
| 656 | + |
| 657 | +\pnum |
| 658 | +The type of a \grammarterm{lambda-expression} (which is also the type of the |
| 659 | +closure object) is a unique, unnamed non-union class type, |
| 660 | +called the \defn{closure type}, |
712 | 661 | whose properties are described below.
|
713 |
| -This class type is not an aggregate type~(\ref{dcl.init.aggr}). |
| 662 | + |
| 663 | +\pnum |
714 | 664 | The closure type is declared in the smallest block
|
715 | 665 | scope, class scope, or namespace scope that contains the corresponding
|
716 | 666 | \grammarterm{lambda-expression}. \begin{note} This determines the set of namespaces and
|
717 | 667 | classes associated with the closure type~(\ref{basic.lookup.argdep}). The parameter
|
718 | 668 | types of a \grammarterm{lambda-declarator} do not affect these associated namespaces and
|
719 |
| -classes. \end{note} An implementation may define the closure type differently from what |
| 669 | +classes. \end{note} The closure type is not an aggregate type~(\ref{dcl.init.aggr}). |
| 670 | +An implementation may define the closure type differently from what |
720 | 671 | is described below provided this does not alter the observable behavior of the program
|
721 | 672 | other than by changing:
|
722 | 673 |
|
|
734 | 685 | An implementation shall not add members of rvalue reference type to the closure
|
735 | 686 | type.
|
736 | 687 |
|
737 |
| -\pnum |
738 |
| -If a \grammarterm{lambda-expression} does not include a |
739 |
| -\grammarterm{lambda-declarator}, it is as if the \grammarterm{lambda-declarator} were |
740 |
| -\tcode{()}. |
741 |
| -The lambda return type is \tcode{auto}, which is replaced by the |
742 |
| -type specified by the |
743 |
| -\grammarterm{trailing-return-type} if provided and/or deduced from |
744 |
| -\tcode{return} statements as described in~\ref{dcl.spec.auto}. |
745 |
| -\begin{example} |
746 |
| -\begin{codeblock} |
747 |
| -auto x1 = [](int i){ return i; }; // OK: return type is \tcode{int} |
748 |
| -auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from \grammarterm{braced-init-list} |
749 |
| -int j; |
750 |
| -auto x3 = []()->auto&& { return j; }; // OK: return type is \tcode{int\&} |
751 |
| -\end{codeblock} |
752 |
| -\end{example} |
753 |
| - |
754 | 688 | \pnum
|
755 | 689 | The closure type for a non-generic \grammarterm{lambda-expression} has a public
|
756 | 690 | inline function call operator~(\ref{over.call}) whose parameters and return type
|
|
791 | 725 | q(); // OK: outputs \tcode{1a3.14}
|
792 | 726 | \end{codeblock}
|
793 | 727 | \end{example}
|
794 |
| -This function call operator or operator template is declared |
| 728 | + |
| 729 | +\pnum |
| 730 | +In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator}, |
| 731 | +each \grammarterm{decl-specifier} |
| 732 | +shall either be \tcode{mutable} or \tcode{constexpr}. |
| 733 | +The function call operator or operator template is declared |
795 | 734 | \tcode{const}~(\ref{class.mfct.non-static}) if and only if the
|
796 | 735 | \grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} is not
|
797 | 736 | followed by \tcode{mutable}. It is neither virtual nor declared \tcode{volatile}. Any
|
|
820 | 759 | \end{codeblock}
|
821 | 760 | \end{example}
|
822 | 761 |
|
| 762 | +\pnum |
| 763 | +\begin{example} |
| 764 | +\begin{codeblock} |
| 765 | +auto monoid = [](auto v) { return [=] { return v; }; }; |
| 766 | +auto add = [](auto m1) constexpr { |
| 767 | + auto ret = m1(); |
| 768 | + return [=](auto m2) mutable { |
| 769 | + auto m1val = m1(); |
| 770 | + auto plus = [=](auto m2val) mutable constexpr |
| 771 | + { return m1val += m2val; }; |
| 772 | + ret = plus(m2()); |
| 773 | + return monoid(ret); |
| 774 | + }; |
| 775 | +}; |
| 776 | +constexpr auto zero = monoid(0); |
| 777 | +constexpr auto one = monoid(1); |
| 778 | +static_assert(add(one)(zero)() == one()); // OK |
| 779 | + |
| 780 | +// Since \tcode{two} below is not declared \tcode{constexpr}, an evaluation of its \tcode{constexpr} member function call operator |
| 781 | +// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture) |
| 782 | +// in a constant expression. |
| 783 | +auto two = monoid(2); |
| 784 | +assert(two() == 2); // OK, not a constant expression. |
| 785 | +static_assert(add(one)(one)() == two()); // ill-formed: \tcode{two()} is not a constant expression |
| 786 | +static_assert(add(one)(one)() == monoid(2)()); // OK |
| 787 | +\end{codeblock} |
| 788 | +\end{example} |
| 789 | + |
823 | 790 | \pnum
|
824 | 791 | The closure type for a non-generic \grammarterm{lambda-expression} with no
|
825 | 792 | \grammarterm{lambda-capture}
|
|
842 | 809 | the pointer to function shall behave as if it were a
|
843 | 810 | \grammarterm{decltype-specifier} denoting the return type of the corresponding
|
844 | 811 | function call operator template specialization.
|
| 812 | + |
| 813 | +\pnum |
845 | 814 | \begin{note}
|
846 | 815 | If the generic lambda has no \grammarterm{trailing-return-type} or
|
847 | 816 | the \grammarterm{trailing-return-type} contains a placeholder type, return type
|
|
892 | 861 | \end{codeblock}
|
893 | 862 | \end{example}
|
894 | 863 |
|
| 864 | +\pnum |
895 | 865 | The value returned by any given specialization of this conversion function
|
896 | 866 | template is the address of a function \tcode{F} that, when invoked, has the same
|
897 | 867 | effect as invoking the generic lambda's corresponding function call operator
|
|
911 | 881 | \end{codeblock}
|
912 | 882 | \end{example}
|
913 | 883 |
|
| 884 | +\pnum |
914 | 885 | The conversion function or conversion function template is public,
|
915 | 886 | constexpr, non-virtual, non-explicit, const, and has a non-throwing exception
|
916 | 887 | specification~(\ref{except.spec}).
|
|
953 | 924 | the \grammarterm{compound-statement} of the \grammarterm{lambda-expression},
|
954 | 925 | with semantics as described in~\ref{dcl.fct.def.general}.
|
955 | 926 |
|
| 927 | +\pnum |
| 928 | +The closure type associated with a \grammarterm{lambda-expression} has no |
| 929 | +default constructor and a deleted copy assignment operator. It has a |
| 930 | +defaulted copy constructor and a defaulted move constructor~(\ref{class.copy}). |
| 931 | +\begin{note} These special member functions are implicitly defined as |
| 932 | +usual, and might therefore be defined as deleted. \end{note} |
| 933 | + |
| 934 | +\pnum |
| 935 | +The closure type associated with a \grammarterm{lambda-expression} has an |
| 936 | +implicitly-declared destructor~(\ref{class.dtor}). |
| 937 | + |
| 938 | +\pnum |
| 939 | +A member of a closure type shall not be |
| 940 | +explicitly instantiated~(\ref{temp.explicit}), |
| 941 | +explicitly specialized~(\ref{temp.expl.spec}), or |
| 942 | +named in a \tcode{friend} declaration~(\ref{class.friend}). |
| 943 | + |
| 944 | +\rSec3[expr.prim.lambda.capture]{Captures}% |
| 945 | + |
| 946 | +\begin{bnf} |
| 947 | +\nontermdef{lambda-capture}\br |
| 948 | + capture-default\br |
| 949 | + capture-list\br |
| 950 | + capture-default \terminal{,} capture-list |
| 951 | +\end{bnf} |
| 952 | + |
| 953 | +\begin{bnf} |
| 954 | +\nontermdef{capture-default}\br |
| 955 | + \terminal{\&}\br |
| 956 | + \terminal{=} |
| 957 | +\end{bnf} |
| 958 | + |
| 959 | +\begin{bnf} |
| 960 | +\nontermdef{capture-list}\br |
| 961 | + capture \terminal{...\opt}\br |
| 962 | + capture-list \terminal{,} capture \terminal{...\opt} |
| 963 | +\end{bnf} |
| 964 | + |
| 965 | +\begin{bnf} |
| 966 | +\nontermdef{capture}\br |
| 967 | + simple-capture\br |
| 968 | + init-capture |
| 969 | +\end{bnf} |
| 970 | + |
| 971 | +\begin{bnf} |
| 972 | +\nontermdef{simple-capture}\br |
| 973 | + identifier\br |
| 974 | + \terminal{\&} identifier\br |
| 975 | + \terminal{this}\br |
| 976 | + \terminal{* this} |
| 977 | +\end{bnf} |
| 978 | + |
| 979 | +\begin{bnf} |
| 980 | +\nontermdef{init-capture}\br |
| 981 | + identifier initializer\br |
| 982 | + \terminal{\&} identifier initializer |
| 983 | +\end{bnf} |
| 984 | + |
| 985 | +\pnum |
| 986 | +The body of a \grammarterm{lambda-expression} may refer to variables |
| 987 | +with automatic storage duration and the \tcode{*this} object (if any) |
| 988 | +of enclosing block scopes by capturing those entities, as described |
| 989 | +below. |
| 990 | + |
956 | 991 | \pnum
|
957 | 992 | If a \grammarterm{lambda-capture} includes a \grammarterm{capture-default} that
|
958 | 993 | is \tcode{\&}, no identifier in a \grammarterm{simple-capture} of that
|
|
1292 | 1327 | \end{codeblock}
|
1293 | 1328 | \end{example}
|
1294 | 1329 |
|
1295 |
| -\pnum |
1296 |
| -The closure type associated with a \grammarterm{lambda-expression} has no |
1297 |
| -default constructor and a deleted copy assignment operator. It has a |
1298 |
| -defaulted copy constructor and a defaulted move constructor~(\ref{class.copy}). |
1299 |
| -\begin{note} These special member functions are implicitly defined as |
1300 |
| -usual, and might therefore be defined as deleted. \end{note} |
1301 |
| - |
1302 |
| -\pnum |
1303 |
| -The closure type associated with a \grammarterm{lambda-expression} has an |
1304 |
| -implicitly-declared destructor~(\ref{class.dtor}). |
1305 |
| - |
1306 |
| -\pnum |
1307 |
| -A member of a closure type shall not be |
1308 |
| -explicitly instantiated~(\ref{temp.explicit}), |
1309 |
| -explicitly specialized~(\ref{temp.expl.spec}), or |
1310 |
| -named in a \tcode{friend} declaration~(\ref{class.friend}). |
1311 |
| - |
1312 | 1330 | \pnum
|
1313 | 1331 | When the \grammarterm{lambda-expression} is evaluated, the entities that are
|
1314 | 1332 | captured by copy are used to direct-initialize each corresponding non-static data member
|
|
5030 | 5048 | If the odr-use occurs in an invocation
|
5031 | 5049 | of a function call operator of a closure type,
|
5032 | 5050 | it no longer refers to \tcode{this} or to an enclosing automatic variable
|
5033 |
| -due to the transformation~(\ref{expr.prim.lambda}) |
| 5051 | +due to the transformation~(\ref{expr.prim.lambda.capture}) |
5034 | 5052 | of the \grammarterm{id-expression} into
|
5035 | 5053 | an access of the corresponding data member.
|
5036 | 5054 | \begin{example}
|
|
0 commit comments