mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
added templates/ifconst.yo
This commit is contained in:
parent
c420605389
commit
6d487dd6a9
10 changed files with 116 additions and 16 deletions
|
@ -11,14 +11,11 @@ C17 etc:
|
|||
|
||||
?? not found: Extending static_assert N3928
|
||||
|
||||
--> Wording for constexpr lambda P0170R1
|
||||
--> Lambda capture of *this by Value P0018R3
|
||||
1--> Construction Rules for enum class variables P0138R2
|
||||
|
||||
Dynamic memory allocation for over-aligned data P0035R4
|
||||
Guaranteed copy elision P0135R1
|
||||
Refining Expression Evaluation Order for Idiomatic C++ P0145R3
|
||||
1-->constexpr if P0292R2
|
||||
Template argument deduction for class templates P0091R3
|
||||
Declaring non-type template parameters with auto P0127R2
|
||||
Using attribute namespaces without repetition P0028R4
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
* The sections about implementing binary operators received an overhaul.
|
||||
|
||||
* The section `Adding binary operators to classes' was rewritten
|
||||
* The section `Adding binary operators to classes' was rewritten.
|
||||
|
||||
* Added descriptions of operator new[](size) and operator delete[](pointer)
|
||||
* Added descriptions of operator new[](size) and operator delete[](pointer).
|
||||
|
||||
* Added preview intro/cpp17.yo on the next C++17 standard
|
||||
* The section about lambda-expressions was extended with descriptions of new
|
||||
features offered by C++17.
|
||||
|
||||
* Added preview intro/cpp17.yo on the next C++17 standard.
|
||||
|
||||
* Added a section about selection statements with initializers to the
|
||||
`First Impression Of C++' chapter.
|
||||
|
@ -14,9 +17,11 @@
|
|||
|
||||
* Added a section about std::exchange to the Generic Algorithms chapter.
|
||||
|
||||
* Added a section about `if constexpr' to the Function Templates chapter.
|
||||
|
||||
* Added a section about folding expressions to the Class Templates chapter.
|
||||
|
||||
* Typos fixed.
|
||||
* Fixed several typos.
|
||||
|
||||
C++-annotations (10.6.0)
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ sect(Template Meta Programming)
|
|||
|
||||
subsubsect(An illustrative example)
|
||||
includefile(advancedtemplates/example)
|
||||
|
||||
|
||||
subsect(Templates: Iterations by Recursion)
|
||||
includefile(advancedtemplates/iterating)
|
||||
|
||||
|
|
|
@ -88,12 +88,15 @@ includefile(functiontemplates/nameresolution)
|
|||
lsect(FUNCTIONSELECTION)(The function selection mechanism)
|
||||
includefile(functiontemplates/selection)
|
||||
|
||||
sect(Determining the template type parameters)
|
||||
subsect(Determining the template type parameters)
|
||||
includefile(functiontemplates/determining)
|
||||
|
||||
sect(SFINAE: Substitution Failure Is Not An Error)
|
||||
includefile(functiontemplates/sfinae)
|
||||
|
||||
lsect(IFCONST)(C++17: Conditional function definitions using `if constexpr')
|
||||
includefile(functiontemplates/ifconst)
|
||||
|
||||
sect(Summary of the template declaration syntax)
|
||||
includefile(functiontemplates/summary)
|
||||
|
||||
|
|
30
annotations/yo/functiontemplates/ifconst.yo
Normal file
30
annotations/yo/functiontemplates/ifconst.yo
Normal file
|
@ -0,0 +1,30 @@
|
|||
The i(C++17) standard offers the tt(if constexpr (cond))
|
||||
syntax. Although it can be used in all situations where a standard tt(if)
|
||||
selection statement can be used, its specific use is encountered with
|
||||
function templates: ti(if constexpr) allows the compiler to instantiate
|
||||
elements of a template function, depending on the compile-time evaluation of
|
||||
the tt(if constexpr's (cond)) clause.
|
||||
|
||||
Here is an example:
|
||||
verbinsert(-ns4 //ifconst examples/lambdaconstexpr.cc)
|
||||
itemization(
|
||||
it() At lines 7 and 9 tt(if constexpr) statements start. Since tt(value)
|
||||
is a template non-type parameter its value is compile-time available,
|
||||
and so are the values of the condition sections.
|
||||
it() In line 15 tt(fun<4>()) is called: the condition in line 7 is
|
||||
therefore tt(true), and the condition in line 9 is tt(false).
|
||||
it() The compiler therefore instantiates tt(fun<4>()) this way:
|
||||
verb(
|
||||
void fun<4>()
|
||||
{
|
||||
positive();
|
||||
}
|
||||
)
|
||||
)
|
||||
Note that the tt(if constexpr) statements themselves do not result in
|
||||
executable code: it is used by the compiler to em(select) which part(s) it
|
||||
should instantiate. In this case only tt(positive), which must be available
|
||||
before the program's linking phase can properly complete.
|
||||
|
||||
|
||||
|
|
@ -25,6 +25,7 @@ Derived der{{value}, "hello world"};
|
|||
// initialization of the (first) base class.
|
||||
)
|
||||
|
||||
dit(if constexpr)
|
||||
dit(Evaluation order of operands of operators)
|
||||
|
||||
Up to C++17, the evaluation order of expressions of operands of binary
|
||||
|
@ -76,6 +77,12 @@ void function(int selector)
|
|||
}
|
||||
)
|
||||
|
||||
dit(if constexpr)
|
||||
|
||||
The tt(if constexpr) syntax can be used (in particular in templates)
|
||||
to instantiate statements depending on conditions that can be evaluated
|
||||
compile-time. See section ref(IFCONST).
|
||||
|
||||
dit(Keywords `export' and `register')
|
||||
|
||||
The keywords ti(export) and ti(register) are no longer used, but are still
|
||||
|
|
|
@ -107,9 +107,6 @@ includefile(stl/lambda)
|
|||
subsect(Generic lambda expressions)
|
||||
includefile(stl/lambdac14)
|
||||
|
||||
includefile(stl/lambdaconstexpr)
|
||||
|
||||
|
||||
sect(Regular Expressions)
|
||||
includefile(stl/regularexp)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
constexpr int add(int n)
|
||||
{
|
||||
return [n] { return n > 10 ? n - 10 : n + 10; }();
|
||||
// return [n] () constexpr { return n > 10 ? n - 10 : n + 10; }();
|
||||
return [n] { return n > 10 ? n - 10 : n + 10; }();
|
||||
}
|
||||
|
||||
auto id = [] (int n ) constexpr { return n; };
|
||||
|
@ -37,3 +38,22 @@ auto add3 = [](auto m1) constexpr
|
|||
};
|
||||
};
|
||||
|
||||
//ifconst
|
||||
void positive();
|
||||
void negative();
|
||||
|
||||
template <int value>
|
||||
void fun()
|
||||
{
|
||||
if constexpr (value > 0)
|
||||
positive();
|
||||
else if constexpr (value < 0)
|
||||
negative();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
fun<4>();
|
||||
}
|
||||
//=
|
||||
|
||||
|
|
|
@ -24,4 +24,13 @@ Lamba expressions solve these problems. A i(lambda expression) defines an
|
|||
i(anonymous function object) which may immediately be passed to functions
|
||||
expecting function object arguments, as explained in the next few sections.
|
||||
|
||||
According to the C++ standard, lambda expressions em(provide a concise way to
|
||||
create simple function objects.) The emphasis here is on em(simple): a lambda
|
||||
expression's size should be comparable to the size of inline-functions: just
|
||||
one or maybe two statements. If you need more code, then encapsulate that code
|
||||
in a separate function which is then called from inside the lambda
|
||||
expression's compound statement, or consider designing a separate function
|
||||
object.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -24,13 +24,45 @@ operator. Here is an example of a lambda expression:
|
|||
The function call operator of the closure object created by this lambda
|
||||
expression expects two tt(int) arguments and returns their product. It is an
|
||||
inline tt(const) member of the closure type. To drop the tt(const) attribute,
|
||||
the lamba expression should specify tt(mutable), as follows:
|
||||
the lamba expression should specify hi(lambda: mutable) tt(mutable), as
|
||||
follows:
|
||||
verb(
|
||||
[](int x, int y) mutable
|
||||
...
|
||||
)
|
||||
The lambda-declarator may be omitted, if no parameters are defined. The
|
||||
parameters in a lamba declarator may not be given default arguments.
|
||||
The lambda-declarator may be omitted, if no parameters are defined, but
|
||||
when specifying tt(mutable) (or tt(constexpr), see below) the
|
||||
lambda-declarator must at least start with an empty set of parenthese. The
|
||||
parameters in a lamba declarator cannot be given default arguments.
|
||||
|
||||
Declarator specifiers can be tt(mutable), or (starting with i(C++17))
|
||||
tt(constexpr), or both. A tt(constexpr) lambda-expression is itself a
|
||||
tt(constexpr), which may be compile-time evaluated if its arguments qualify as
|
||||
const-expressions. Moreover, if a lambda-expression is defined inside a
|
||||
tt(constexpr) function then the lambda-expression itself must qualify as a
|
||||
tt(constexpr), and explicitly specifying the tt(constexpr) declarator
|
||||
specifier is not required. The following function definitions, therefore, are
|
||||
identical:
|
||||
verb(
|
||||
// starting with C++17:
|
||||
int constexpr change10(int n)
|
||||
{
|
||||
return [n]
|
||||
{
|
||||
return n > 10 ? n - 10 : n + 10;
|
||||
}();
|
||||
}
|
||||
|
||||
// starting with C++17:
|
||||
int constexpr change10(int n)
|
||||
{
|
||||
return [n] () constexpr
|
||||
{
|
||||
return n > 10 ? n - 10 : n + 10;
|
||||
}();
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
A closure object as defined by the above lamda expression could be used e.g.,
|
||||
in combination with the tt(accumulate) (cf. section ref(ACCU)) generic
|
||||
|
|
Loading…
Reference in a new issue