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