added templates/ifconst.yo

This commit is contained in:
Frank B. Brokken 2016-11-17 14:04:51 +01:00
parent c420605389
commit 6d487dd6a9
10 changed files with 116 additions and 16 deletions

View file

@ -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

View file

@ -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)

View file

@ -32,7 +32,7 @@ sect(Template Meta Programming)
subsubsect(An illustrative example)
includefile(advancedtemplates/example)
subsect(Templates: Iterations by Recursion)
includefile(advancedtemplates/iterating)

View file

@ -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)

View 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.

View file

@ -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

View file

@ -107,9 +107,6 @@ includefile(stl/lambda)
subsect(Generic lambda expressions)
includefile(stl/lambdac14)
includefile(stl/lambdaconstexpr)
sect(Regular Expressions)
includefile(stl/regularexp)

View file

@ -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>();
}
//=

View file

@ -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.

View file

@ -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