C++ Modern and Lucid C++ for Professional Programmers

Similar documents
SFU CMPT Topic: Function Objects

COMP6771 Advanced C++ Programming

C++1z: Concepts-Lite !!! !!! !!!! Advanced Developer Conference C slides:

C++ Modern and Lucid C++ for Professional Programmers

Functions. Ali Malik

C++ Modern and Lucid C++ for Professional Programmers

P0984R0 - All (*)()-Pointers Replaced by Ideal Lambdas Functions Objects Obsoleted by Lambdas

Functions. Ali Malik

Lambda functions. Zoltán Porkoláb: C++11/14 1

C++ for numerical computing - part 2

The STL <functional> Library

Modern and Lucid C++ Advanced for Professional Programmers. Part 1 C Plus Plus Recap. Department I - C Plus Plus

Object-Oriented Programming

Instantiation of Template class

Overload Resolution. Ansel Sermersheim & Barbara Geller ACCU / C++ June 2018

Introduction to C++ Systems Programming

CSCI 104 Templates. Mark Redekopp David Kempe

Abstraction and Encapsulation. Benefits of Abstraction & Encapsulation. Concrete Types. Using Typedefs to streamline classes.

Chapter 15 - C++ As A "Better C"

2 ADT Programming User-defined abstract data types

What will happen if we try to compile, link and run this program? Do you have any comments to the code?

Outline. User-dened types Categories. Constructors. Constructors. 4. Classes. Concrete classes. Default constructor. Default constructor

use static size for this buffer

Functors. Cristian Cibils

C The new standard

CSCI 104 Templates. Mark Redekopp David Kempe

Lecture 2 Polymorphism, Traits, Policies, and Inheritance

Tokens, Expressions and Control Structures

Overload Resolution. Ansel Sermersheim & Barbara Geller Amsterdam C++ Group March 2019

CHAPTER 1 Introduction to Computers and Programming CHAPTER 2 Introduction to C++ ( Hexadecimal 0xF4 and Octal literals 031) cout Object

Modern and Lucid C++ Advanced for Professional Programmers. Part 3 Move Semantics. Department I - C Plus Plus Advanced

CS 247: Software Engineering Principles. C++ Templates. Reading: Eckel, Vol. 2 Ch. 5 Templates in Depth. U Waterloo CS247 (Spring 2017) p.

Functional Programming in C++

COEN244: Class & function templates

Working with Batches of Data

Program construction in C++ for Scientific Computing

Elevate your Code to Modern C++ with Automated Tooling. Peter Sommerlad

Overloaded Operators, Functions, and Students

CS

C++11 and Compiler Update

Objects Managing a Resource

10. Functions (Part 2)

CSCI-1200 Data Structures Fall 2009 Lecture 20 Hash Tables, Part II

IV. Stacks. A. Introduction 1. Consider the 4 problems on pp (1) Model the discard pile in a card game. (2) Model a railroad switching yard

Outline. 1 About the course

CSCI-1200 Data Structures Fall 2018 Lecture 21 Hash Tables, part 1

Part XI. Algorithms and Templates. Philip Blakely (LSC) C++ Introduction 314 / 370

Value categories. PRvalues. Lvalues

Advanced Systems Programming

An introduction to C++ template programming

CS 251 INTERMEDIATE SOFTWARE DESIGN SPRING C ++ Basics Review part 2 Auto pointer, templates, STL algorithms

CSCI-1200 Data Structures Fall 2017 Lecture 23 Functors & Hash Tables, part II

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

Templates. Zoltán Porkoláb: C++11/14 1

1/29/2011 AUTO POINTER (AUTO_PTR) INTERMEDIATE SOFTWARE DESIGN SPRING delete ptr might not happen memory leak!

CHAPTER 4 FUNCTIONS. 4.1 Introduction

MODERN AND LUCID C++ ADVANCED

COMP6771 Advanced C++ Programming

Introduction to Programming

MODULE 37 --THE STL-- ALGORITHM PART V

The STL <functional> Library

Appendix. Grammar. A.1 Introduction. A.2 Keywords. There is no worse danger for a teacher than to teach words instead of things.

Ch. 12: Operator Overloading

Review. What is const member data? By what mechanism is const enforced? How do we initialize it? How do we initialize it?

TDDD38 - Advanced programming in C++

AN OVERVIEW OF C++ 1

Module Operator Overloading and Type Conversion. Table of Contents

C++ Basics. Data Processing Course, I. Hrivnacova, IPN Orsay

I BCS-031 BACHELOR OF COMPUTER APPLICATIONS (BCA) (Revised) Term-End Examination. June, 2015 BCS-031 : PROGRAMMING IN C ++

Basic Types, Variables, Literals, Constants

CS 376b Computer Vision

A Parallel Algorithms Library N3724

TDDD38 - Advanced programming in C++

The Ada Standard Generic Library (SGL)

III. Classes (Chap. 3)

3.Constructors and Destructors. Develop cpp program to implement constructor and destructor.

Tutorial 7. Y. Bernat. Object Oriented Programming 2, Spring Y. Bernat Tutorial 7

Cpt S 122 Data Structures. Templates

COMP322 - Introduction to C++ Lecture 01 - Introduction

COMP6771 Advanced C++ Programming

Operators. Lecture 3 COP 3014 Spring January 16, 2018

W3101: Programming Languages C++ Ramana Isukapalli

Agenda. The main body and cout. Fundamental data types. Declarations and definitions. Control structures

Structuur van Computerprogramma s 2

class Polynomial { public: Polynomial(const string& N = "no name", const vector<int>& C = vector<int>());... };

calling a function - function-name(argument list); y = square ( z ); include parentheses even if parameter list is empty!

Fast Introduction to Object Oriented Programming and C++

Introduction. Contents. Homogeneous interface for variant<ts...>, any and optional<t>

MODULE 35 --THE STL-- ALGORITHM PART III

Introduction to Programming using C++

G Programming Languages Spring 2010 Lecture 11. Robert Soulé, New York University

Outline. 1 Function calls and parameter passing. 2 Pointers, arrays, and references. 5 Declarations, scope, and lifetimes 6 I/O

I m sure you have been annoyed at least once by having to type out types like this:

CSCI-1200 Data Structures Fall 2015 Lecture 24 Hash Tables

Using Enum Structs as Bitfields

Functions and Recursion

Final exam. Final exam will be 12 problems, drop any 2. Cumulative up to and including week 14 (emphasis on weeks 9-14: classes & pointers)

Implicit Evaluation of auto Variables and Arguments

Arrays. Returning arrays Pointers Dynamic arrays Smart pointers Vectors

Cpt S 122 Data Structures. Introduction to C++ Part II

Transcription:

Informatik C++ Modern and Lucid C++ for Professional Programmers part 9 Prof. Peter Sommerlad Institutsleiter IFS Institute for Software Rapperswil, HS 2015

Functors and Parameterizing STL Functors, Lambdas, Standard Functors, std::function<>

Function Objects struct donothingfunctor{ We can overload the function call operator as member of a class -> Functor class, instance: functor object ret operator()(params) {... ; void operator()()const{ Two pairs of parentheses required! usually const-member, unless changing member variables of the function object Member variables can keep memory! donothingfunctor{(); construct and call 3

Example: Functor with memory #include <iostream> #include <algorithm> #include <vector> struct averager { void operator()(double d) { accumulator += d; ++counter; double sum() const { return accumulator; double count() const { return counter; double average() const { return sum()/count(); private: double accumulator{; unsigned counter{; ; int main(){ std::vector<double> v{7,4,1,3,5,3.3,4.7; auto const res=for_each(v.begin(),v.end(),averager{); std::cout << "sum = " << res.sum() << '\n' << "count = " << res.count() << '\n' << "average = "<< res.average() << '\n'; res is resulting averager object 4

Function/Functor Terminology Function: unary function, binary function,... Operator function: unary operator, binary operator Functor: unary functor, binary functor Predicate: function/functor with bool result unary predicate: a property of its argument binary predicate: compare two arguments 5

Generator Functors std::vector<int> v; int x{; // memory for lambda below generate_n(std::back_inserter(v),10,[&x]{ ); ++x; return x*x; generate() algorithm requires function with "memory" if not all values should be the same (nullary function, no parameters) Lambda requires variable captured by & or mutable lambda class make_squares{ int x{; public: int operator()() { ++x; return x*x; ; //... generate(v.begin(),v.end(),make_squares{); 6

Lambda Function Syntax Defining Inline Functions definition auto const g=[](char c)->char{return std::toupper(c);; g('a'); call auto const for function variable from Lambda is used to call function [] introduces Lambda function can contain captures, e.g., [=] or [&] to access variables (parameters), as with other functions, but can be auto -> trailing return type, if cannot be deduced (not needed) body block with statements 7

Recap Lambda Rules [capture](parameters)mutableopt->return_type{body Capture: [=], [&], [var=value] Parameters: auto p1, int p2, auto mutable: allow changing capture variables in body Return_type: typically deduced automatically Body: return statement(s) provide return type implicitly 8

Lambda Captures [capture](parameters)mutableopt->return_type{body Capture: [=] - default implicit capture variables used in body by value [&] - default capture variable used in body by reference [var=value] - introduce new capture variable with value combinations of specific captures with a default [=,&out] - capture all by copy, but out by reference [&,=x] - capture all by reference, but x by copy/value Guideline: always capture variables explicitly 9

Lambda Special Case: mutable generate_n(std::back_inserter(v),10,[x=0]() mutable { return ++x, x*x; // mutable allows change allow changing x ); introduce new capture variable x variables captured by copy (=) are const within the lambda, unless... the lambda is marked mutable, and the lambda gets its own copy of the variable, or the lambda defines its capture with an initializer lambdas are mapped internally to functors 10

Lambdas are functors A C++ compiler internally maps lambdas to functor objects with an unaccessible/hidden class name [&x]{ ++x; return x*x; struct _unknown_generator_name_{ _unknown_generator_name_(int &x):x{x{ auto operator()() const { ++x; return x*x; private: int &x; ; [](char c)->char{ return std::toupper(c); struct _unknown_converter_name_ { auto operator()(char c) const ->char{ return std::toupper(c); ; 11

Lambdas in Member Functions this-> struct DemoLambdaMemberVariables { int x{; std::vector<int> demoaccessingmemberfromlambda() { std::vector<int> v; generate_n(back_inserter(v),10,[=] { return ++x, x*x; // member x can be changed ); return v; ; capture this by copy Captured member variables are always captured by reference, even if the default is [=] Reason: this is a pointer (reference) and if copied, member variables are referred from it this can not be captured by reference 12

Standard Functor template Classes transform(v.begin(),v.end(),v.begin(),[](int x){return -x;); transform(v.begin(),v.end(),v.begin(),std::negate<int>{); Lambdas make applying transform etc. quite easy However, if there is only a simple expression used, there is a chance for reuse of the standard library's functor classes for almost all operators also relational operators, e.g., sorting in descending order sort(v.begin(),v.end(),std::greater<>{); parameter type deduced 13

standard functor classes #include <functional> binary arithmetic and logical plus<> (+) minus<> (-) divides<> (/) multiplies<> (*) modulus<> (%) logical_and<> (&&) logical_or<> ( ) transform(v.begin(),v.end(),v.begin(), v.begin(),std::multiplies<>{); unary negate<> (-) logical_not<> (!) binary comparison less<> (<) less_equal<> (<=) equal_to<> (==) greater_equal<> (>=) greater<> (>) not_equal_to<> (!=) 14

Parameterize Associative Containers std::set<int,std::greater<>> reverse_int_set{; Associative containers allow an additional template argument for the comparison operation it must be a functor class giving a binary predicate predicate must be irreflexive and transitive Own functors can provide special sort order, e.g., case-less comparison of strings caution: requirements for sorting must be fulfilled, e.g. >= (std::greater_equal) is not allowed (is reflexive!) 15

Example: set<string> for dictionary #include <set> #include <functional> #include <algorithm> #include <cctype> #include <iterator> #include <iostream> struct caseless{ using string=std::string; bool operator()(string const &l, string const &r){ return std::lexicographical_compare( l.begin(),l.end(),r.begin(),r.end(), [](char l,char r){ return std::tolower(l) < std::tolower(r); ); ; int main(){ using std::string; using caseless_set=std::multiset<string,caseless>; using in=std::istream_iterator<string>; caseless_set wlist{in{std::cin,in{; std::ostream_iterator<string> out{std::cout,"\n"; copy(wlist.begin(),wlist.end(),out); binary predicate strings as ranges lambda as binary predicate on char pass predicate functor as template argument 16

How to keep functors around? In situations where you not only provide a functor but want to take a function or functor as parameter, e.g., in a constructor and later apply it, what should be the type of the (member) variable and the parameter? foo(double f(double)); doesn't work with functors neither does your specific functor type for others 2 options: template typename parameter (later) std::function<double(double)> 17

std::function<signature> std::function<bool(int)> apredicate{; Universal function holder can store functions, functor instances or lambdas signature must be compatible with the SIGNATURE function template argument can be reassigned or emptied can be empty -> might need to check if (apredicate) { // implicit bool conversion: is valid? cout << "pred(42) is " << apredicate(42) << '\n'; else { cout << "empty function\n"; 18

#include <functional> #include <iostream> Example: using std::function<> void apply_and_print(std::ostream& cout, std::function<bool(int)> apredicate) { if (apredicate) { // implicit bool conversion cout << "pred(42) is " << apredicate(42) << '\n'; else { cout << "empty function holder\n"; function parameter check for validity call operator() of int main(){ using std::cout; cout << std::boolalpha; // true/false in output std::function<bool(int)> apredicate{; apply_and_print(cout,apredicate); apredicate = [](int i){return i%2;; apply_and_print(cout,apredicate); apredicate = std::not1(apredicate); apply_and_print(cout,apredicate); apredicate = nullptr; apply_and_print(cout,apredicate); default is empty -> invalid to call std::not1() creates logically negated unary predicate functor nullptr assignment makes function empty 19

std::function with member functions #include <functional> #include <iostream> member function to wrap struct X { int calc(int i) const { return x*i; private: int x{7; ; make variable const to avoid invalid function objects (general rule!) int main(){ std::function<int (X const &,int)> const f{&x::calc; X const anx{; std::cout << f(anx,6); must pass object as this argument explicitly member function pointer must specify & address-of operator to member 20

What is a member-(function) pointer? It is possible to refer to individual class members using "pointer-to-members" e.g., to handle different members of the same type by the same function syntax of the type: type Class::* varname; initialize such a value by: &Class::member This extends to "pointer-to-member-functions" syntax: resulttype (Class::*)(params) 21

Example Pointer to Members.* struct X { void foo() const { std::cout << a << " foo\n"; void bar() const { std::cout << b << " bar\n"; int a; int b; ; must match m-f signature including const and parameters void doit(void (X::*mfunc)() const, X const &x){ (x.*mfunc)(); // parenthesis needed void change(int X::*memvar, X& x, int val){ use operator.* for member function pointer () required - precedence x.*memvar = val; use operator.* for pointer to member access int main(){ X x{1,2; doit(&x::foo,x); doit(&x::bar,x); change(&x::a,x,42); change(&x::b,x,43); doit(&x::foo,x); doit(&x::bar,x); 1 foo 2 bar 42 foo 43 bar 22

std::function calling member function auto g=std::function<void(x const&, int)>{&x::foo; X x{42,43; g(x,1); // calls -> x.foo(1) x.bar(2); struct X { void foo(int) const ; void bar(int) const ; int a; int b; ; std::function for a member function makes passing the this object explicit Here you see, that what is left of the. operator is actually passed to the member function as an argument 23

Creating your own iterator types #include <iterator> algorithms are parameterized by functors but also by iterators You can create or wrap iterators using boost::iterators library #include <boost/iterator/counting_iterator.hpp> #include <boost/iterator/filter_iterator.hpp> #include <boost/iterator/transform_iterator.hpp> Or you can implement your own iterators (see C++ advanced) with the help of <boost/operators.hpp> 24

Recap: Iterator Categories Different algorithms require different strengths of iterators InputIterator - read sequence once OutputIterator - write results, without designating an end ForwardIterator - read/write sequence, multiple passes BidirectionalIterator - read/write sequence, back-forth RandomAccessIterator - read/write/indexed sequence more versatile iterator can be used for more efficient algorithm Iterator's capabilities can be determined at compile time 25

Boost Iterator Library #include <boost/iterator/counting_iterator.hpp> #include <boost/iterator/filter_iterator.hpp> #include <boost/iterator/transform_iterator.hpp> Several pre-defined adapters with factory functions, for example counting filtering transforming See also http://www.boost.org/doc/libs/1_59_0/libs/iterator/doc/ 26

Example: using Boost Iterator struct odd{ bool operator()(int n)const{return n%2; ; int main(){ using counter=boost::counting_iterator<int>; std::vector<int> v(counter{1,counter{11); std::ostream_iterator<int> out{std::cout,", "; copy(v.begin(),v.end(),out); std::cout << '\n'; using boost::make_filter_iterator; copy(make_filter_iterator(odd{,v.begin(),v.end()), make_filter_iterator(odd{,v.end(),v.end()), out); std::cout << '\n'; using boost::make_transform_iterator; auto square=[](auto x){ return x*x;; copy(make_transform_iterator(v.begin(),square), make_transform_iterator(v.end(),square), out); functor for filtering counting iterator filter iterator, only odd values provided transform iterator applies function/functor/ lambda for each value 27

Summary Parameterize the standard library through Functors Lambdas Iterators construct your own with boost::iterator library Store and pass functions / function objects in std::function<> 28