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