Modernes C++ Träume und Alpträume

Similar documents
Geheimnisse der Move-Semantik

Introduction to Move Semantics in C++ C and C

Rvalue References, Move Semantics, Universal References

Rvalue References & Move Semantics

Copyie Elesion from the C++11 mass. 9 Sep 2016 Pete Williamson

Value categories. PRvalues. Lvalues

C The new standard

COMP6771 Advanced C++ Programming

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

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

Special Member Functions

aerix consulting C++11 Library Design Lessons from Boost and the Standard Library

Part X. Advanced C ++

Move Semantics, Rvalue References, and Perfect Forwarding

Overview of C Feabhas Ltd 2012

Bind Returned/Initialized Objects to the Lifetime of Parameters, Rev0

Assignment #1 Advanced Programming in C /2018. NPRG051 Advanced programming in C++ - Assignment #1

The paramaterless ctor (aka default ctor)

Part III. Advanced C ++

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

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

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

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

Object-Oriented Principles and Practice / C++

Special Member Functions. Compiler-Generated Destructor. Compiler-Generated Default Constructor. Special Member Functions

TDDD38 - Advanced programming in C++

CS93SI Handout 04 Spring 2006 Apr Review Answers

BYOD - WEEK 3 AGENDA. Dictionary Encoding. Organization. Sprint 3

The issues. Programming in C++ Common storage modes. Static storage in C++ Session 8 Memory Management

Advanced Systems Programming

EXP54-CPP. Do not access an object outside of its lifetime

Object-Oriented Principles and Practice / C++

Overview. 1. Expression Value Categories 2. Rvalue References 3. Templates 4. Miscellaneous Hilarity 2/43

Using Enum Structs as Bitfields

04-19 Discussion Notes

A brief introduction to C++

Object-Oriented Principles and Practice / C++

COP4530 Data Structures, Algorithms and Generic Programming Recitation 4 Date: September 14/18-, 2008

C++11/14 Rocks. Clang Edition. Alex Korban

Financial computing with C++

18. Dynamic Data Structures I. Dynamic Memory, Addresses and Pointers, Const-Pointer Arrays, Array-based Vectors

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

use static size for this buffer

std::optional from Scratch

Vector and Free Store (Vectors and Arrays)

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

On launder() Which Problem shall launder() solve? N. Josuttis: P0532R0: On launder()

UEE1303(1070) S12: Object-Oriented Programming Operator Overloading and Function Overloading

CSE 374 Programming Concepts & Tools. Hal Perkins Fall 2015 Lecture 19 Introduction to C++

Advanced C++ Topics. Alexander Warg, 2017

CS250 Final Review Questions

CS

Advanced Programming & C++ Language

Homework 4. Any questions?

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

Common Misunderstandings from Exam 1 Material

SFU CMPT Topic: Class Templates

Modern C++, From the Beginning to the Middle. Ansel Sermersheim & Barbara Geller ACCU / C++ November 2017

Function Composition and Return Type Deduction. Anthony Williams. 28th February Abstract

Slide Set 14. for ENCM 339 Fall Steve Norman, PhD, PEng. Electrical & Computer Engineering Schulich School of Engineering University of Calgary

COMP6771 Advanced C++ Programming

CS11 Advanced C++ Spring 2018 Lecture 2

Arizona s First University. ECE 373. Operation Overloading. The Revolution Operation Will Be Televised (and, these slides will be online later today)

Modern and Lucid C++ Advanced for Professional Programmers. Part 7 Compile-Time Computation. Department I - C Plus Plus

C++ Rvalue References Explained

Explicit Conversion Operator Draft Working Paper

CSE 333. Lecture 11 - constructor insanity. Hal Perkins Paul G. Allen School of Computer Science & Engineering University of Washington

Advanced C++ 4/13/2017. The user. Types of users. Const correctness. Const declaration. This pointer and const.

Object-Oriented Programming, Iouliia Skliarova

Operator Overloading in C++ Systems Programming

COMP6771 Advanced C++ Programming

COMP6771 Advanced C++ Programming

COMP6771 Advanced C++ Programming

Operator Dot Wording

Auto - a necessary evil?

EL2310 Scientific Programming

IS0020 Program Design and Software Tools Midterm, Fall, 2004

Lecture 8. Exceptions, Constructor, Templates TDDD86: DALP. Content. Contents Exceptions

CSE 333 Lecture smart pointers

Type Erasure. Nevin :-) Liber Friday, October 29, Chicago C/C++ Users Group Nevin J. Liber All Rights Reserved.

An introduction to. Templates. Generic Programming. Good old C. Metaprogramming 4/13/2017

Object Oriented Design Final Exam (From 3:30 pm to 4:45 pm) Name:

Object-Oriented Programming for Scientific Computing

Database Systems on Modern CPU Architectures

CSE 303: Concepts and Tools for Software Development

엄현상 (Eom, Hyeonsang) School of Computer Science and Engineering Seoul National University COPYRIGHTS 2015 EOM, HYEONSANG ALL RIGHTS RESERVED

Implicit Evaluation of auto Variables and Arguments

A Crash Course in (Some of) Modern C++

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

2 ADT Programming User-defined abstract data types

C++ Functions. Procedural-based Programming. what s a functions

Qualified std::function signatures

Vector and Free Store (Pointers and Memory Allocation)

Introduction to Standard C++

Fast Introduction to Object Oriented Programming and C++

ECE 2400 Computer Systems Programming Fall 2017 Topic 15: C++ Templates

This chapter serves mainly to gather and organize information about iterators. Some new concepts are also introduced for completeness.

Programmazione. Prof. Marco Bertini

ADTs in C++ In C++, member functions can be defined as part of a struct

Modernizing legacy C++ code

Transcription:

Modernes Träume und Alpträume Nicolai M. Josuttis 5/17 217 by IT-communication.com 1 Independent consultant continuously learning since 1962 Nicolai M. Josuttis Systems Architect, Technical Manager finance, manufacturing, automobile, telecommunication Topic SOA (Service Oriented Architecture) Technical Project Management Privacy (contributor of Enigmail) 217 by IT-communication.com 2

http://isocpp.org/std/statu Timeframe (medium) 217 by IT-communication.com 3 The Power of Move Semantics Use a Naive Function returning a Vector of Strings in 11 217 by IT-communication.com 4

Move Semantics of 11 coll: 4 d a t a \ 217 by IT-communication.com 5 Move Semantics of 11 coll: 1 4 d a t a \ 4 d a t a \ 217 by IT-communication.com 6

Move Semantics of 11 coll: 1 4 d a t a \ 4 d a t a \ s+ 8 d a t a d a t a \ 217 by IT-communication.com 7 Move Semantics of 11 coll: 21 4 8 d a t a \ 4 d a t a \ s+ 8 d a t a d a t a \ 217 by IT-communication.com 8

Move Semantics of 11 coll: 2 4 8 destruct temporary d a t a \ 4 d a t a \ s+ d a t a d a t a \ 217 by IT-communication.com 9 Move Semantics of 11 coll: 32 4 8 4 d a t a \ 4 d a t a \ s+ d a t a d a t a \ 217 by IT-communication.com 1

Move Semantics of 11 coll: 3 4 8 4 d a t a \ d a t a \ s+ MAY move coll d a t a d a t a \ 217 by IT-communication.com 11 Move Semantics of 11 retval: 3 4 8 4 d a t a \ d a t a \ s+ MAY move coll d a t a d a t a \ 217 by IT-communication.com 12

Move Semantics of 11 retval: 3 4 8 4 d a t a \ d a t a \ s+ d a t a d a t a \ 217 by IT-communication.com 13 Move Semantics of 11 retval: 3 4 8 4 d a t a \ d a t a \ s+ d a t a d a t a \ 3 217 by IT-communication.com 14

Move Semantics of 11 retval: 4 8 4 d a t a \ d a t a \ s+ d a t a d a t a \ 3 1 4 malloc/new 6 free/delete 217 by IT-communication.com 15 So: What changed with 11? What are the consequences? 217 by IT-communication.com 16

Without Move Semantics Containers have value semantics copy passed new elements into their containers allows to pass rvalues (such as temporaries) This leads to unnecessary copies with 98/3 template <typename T> class vector // insert a copy of elem: void push_back (const T& elem); ; std::vector<std::string> createandinsert () // create a string s // insert a copy of s into coll // s is used and modified afterwards // insert copy of temporary rvalue unnecessary copies unnecessary copy in 98 / 3 // insert copy of s again // but s is no longer used here // may copy coll 217 by IT-communication.com 17 With Move Semantics With rvalue references you can provide move semantics RValue references represent modifiable object where the value is no longer needed so that you can steal their content #include <utility> // declares std::move() template <typename T> class vector // insert a copy of elem: void push_back (const T& elem); // insert elem with its content moved: void push_back (T&& elem); ; declares rvalue reference std::vector<std::string> createandinsert () // create a string s // insert a copy of s into coll // s is used and modified afterwards // move temporary into coll // move s into coll, because s is no longer used // may move coll 217 by IT-communication.com 18

With Move Semantics To support move semantics for non-trivial types you should: provide a move constructor provide a move assignment operator where the move version is optimized to steal contents from the passed object and set the assigned object in a valid but undefined (or initial) state class string int len; // current number of characters char* elems; // array of characters // create a full copy of string (const string& s) : len(s.len) elems = new char[len+1]; // new memory memcpy(elems,s.elems,len+1); class string int len; // create a copy of s with its content moved: string (string&& s) : len(s.len), elems(s.elems) // copy pointer to memory s.elems = nullptr; // otherwise destructor of s // frees stolen memory s.len = ; ; 217 by IT-communication.com 19 Basic Move Support Guarantees for library objects ( 17.6.5.15 [lib.types.movedfrom]): Unless otherwise specified, moved-from objects shall be placed in a valid but unspecified state. Copy as Fallback If no move semantics is provided, copy semantics is used unless move operations are explicitly deleted Default move operations are generated Move constructor and Move assignment operator pass move semantics to member but only if this can't be a problem Only if there is no special member function defined copy constructor assignment operator destructor 217 by IT-communication.com 2

Effect of Default Move Semantics Cust(const std::string& fn, const std::string& ln = "", long i = ) : first(fn), last(ln), id(i) ; friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; std::vector<cust> v; // 3: 11: v.push_back(cust("jim","coe",42)); // 6 exp (cr+cp+cp) 4 exp (cr+cp+mv) Cust c("joe","fix",77); // 4 exp (cr+cp) 4 exp (cr+cp) v.push_back(c); // 2+2 exp (cp+cp) 2 exp (cp+mv) std::cout << "c: " << c << std::endl; // c: [77: joe fix] c: [77: joe fix] v.push_back(std::move(c)); // ---- exp (mv+mv) std::cout << "c: " << c << std::endl; // ---- c: [77:??????] 217 by IT-communication.com 21 (Perfect) Forwarding 217 by IT-communication.com 22

Forwarding Move Semantics You can and have to forward move semantics explicitly: class X; void g (X&); // for variable values void g (const X&); // for constant values void g (X&&); // for values that are no longer used (move semantics) void f (X& t) g(t); // t is non const lvalue => calls g(x&) void f (const X& t) g(t); // t is const lvalue => calls g(const X&) void f (X&& t) g(std::move(t)); // t is non const lvalue => needs std::move() to call g(x&&) // - When move semantics would always be passed, // calling g(t) twice would be a problem X v; const X c; f(v); // calls f(x&) => calls g(x&) f(c); // calls f(const X&) => calls g(const X&) f(x()); // calls f(x&&) => calls g(x&&) f(std::move(v)); // calls f(x&&) => calls g(x&&) 217 by IT-communication.com 23 Example of Improvements for Move Semantics Cust(const std::string& fn, const std::string& ln = "", long i = ) : first(fn), last(ln), id(i) Cust(std::string&& fn, std::string&& ln = "", long i = ) : first(std::move(fn)), last(std::move(ln)), id(i) friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; ; std::vector<cust> v; // 3 (old class): 11: v.push_back(cust("jim","coe",42)); // 6 exp (cr+cp+cp) 217 by IT-communication.com 24 2 exp (cr+mv+mv) Cust c("joe","fix",77); // 4 exp (cr+cp) 2 exp (cr+mv) v.push_back(c); // 2+2 exp (cp+cp) 2 exp (cp+mv) std::cout << "c: " << c << std::endl; // c: [77: joe fix] c: [77: joe fix] v.push_back(std::move(c)); // ---- mallocs (mv+mv) std::cout << "c: " << c << std::endl; // ---- c: [77:??????]

Perfect Forwarding Special semantics for && with template types For temporaries, constants, and variables and the template type knows what they are You can use std::forward<>() to keep this semantics Term "Universal Reference" (introduced by Scott Meyers) Standard term: "Forwarding Reference" (introduced for 17 with N4262) void g (X&); // for variable values void g (const X&); // for constant values void g (X&&); // for values that are no longer used (move semantics) template <typename T> void f (T&& t) // t is universal/forwarding reference g(std::forward<t>(t)); // forwards move semantics // (without forward<>, only calls g(const X&) or g(x&)) X v; const X c; f(v); f(c); f(x()); f(std::move(v)); 217 by IT-communication.com 25 Example of Generic Improvements for Move Semantics template <typename STR1, typename STR2> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) ; friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; std::vector<cust> v; // 3 (old class): 11: v.push_back(cust("jim","coe",42)); // 6 exp (cr+cp+cp) 2 exp (cr+mv) Cust c("joe","fix",77); // 4 exp (cr+cp) 2 exp (cr) v.push_back(c); // 2+2 exp (cp+cp) 2 exp (cp+mv) std::cout << "c: " << c << std::endl; // c: [77: joe fix] c: [77: joe fix] v.push_back(std::move(c)); // ---- exp (mv+mv) std::cout << "c: " << c << std::endl; // ---- c: [77:??????] 217 by IT-communication.com 26

Fixing Broken Usage 217 by IT-communication.com 27 Deducing from Default Call Arguments template <typename STR1, typename STR2> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust d2("tim"); // Error: can't deduce from default call arguments // Error: can't deduce from default call arguments 217 by IT-communication.com 28

Deducing from Default Call Arguments template <typename STR1, typename STR2> ; Cust(STR1&& fn, STR2&& ln = std::string"", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; std::vector<cust> v; v.push_back(cust("jim","coe",42)); same error with: STR2&& ln = ""s Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust d2("tim"); // Error: can't deduce from default call arguments // Error: can't deduce from default call arguments 217 by IT-communication.com 29 Default Template Arguments template <typename STR1, typename STR2 = std::string> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust d2("tim"); 217 by IT-communication.com 3

Default Template Arguments template <typename STR1, typename STR2 = std::string> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust e1d1; const Cust d2"tim"; Cust e1d2; // Error: can't convert Cust to std::string 217 by IT-communication.com 31 Default Template Arguments template <typename STR1, typename STR2 = std::string> Cust(STR1&& fn, STR2&& ln = "", long i = ) ; : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) friend std::ostream& operator << (std::ostream& strm, const Cust& c) return strm << "[" << c.id << ": " << c.first << " " << c.last << "]"; std::vector<cust> v; v.push_back(cust("tim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: Joe Fix] Cust d1"tina"; const Cust d2"bill"; Cust e1d1; // Error: "can't convert Cust to std::string" Cust e2d2; 217 by IT-communication.com 32 Better match than pre-defined copy constructor for non-const object Cust objects objects derived from Cust

Using enable_if<> template <typename STR1, typename STR2 = string, typename std::enable_if<!std::is_same<cust,str1>::value, void*>::type = nullptr> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust e1d1; const Cust d2"tim"; Cust e1d2; // Error: can't convert Cust to std::string 217 by IT-communication.com 33 Using enable_if<> template<typename STR1, typename STR2 = string, typename std::enable_if<!std::is_same <Cust, typename std::remove_reference <typename std::remove_const<str1>::type >::type >::value, void*>::type = nullptr> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) ; Wrong order: typename std::remove_reference< typename std::remove_const<const int&>::type>::type // => const int typename std::remove_const< typename std::remove_reference<const int&>::type>::type // => int 217 by IT-communication.com 34

Type Traits Details std::is_constructible<t, Args> checks whether you can construct T from Args T t(declval<args>()); // must be valid std::is_convertible<from, To> checks whether you can convert From to To To test() return declval<from>(); // must be valid class C explicit C(const C&); std::is_constructible_v<c,c> // yields true std::is_convertible_v<c,c> // yields false 217 by IT-communication.com 35 Using enable_if<> template <typename STR1, typename STR2 = string, typename std::enable_if<std::is_constructible<std::string,str1> ::value, void*>::type = nullptr> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust e1d1; const Cust d2"tim"; Cust e1d2; 217 by IT-communication.com 36

17: Using enable_if<> template <typename STR1, typename STR2 = std::string, std::enable_if_t<std::is_constructible_v<std::string,str1>, void*> = nullptr> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust e1d1; const Cust d2"tim"; Cust e1d2; 217 by IT-communication.com 37 2: Using Concepts template <typename STR1, typename STR2 = std::string> requires std::is_constructible_v<std::string,str1> Cust(STR1&& fn, STR2&& ln = "", long i = ) : first(std::forward<str1>(fn)), last(std::forward<str2>(ln)), id(i) ; std::vector<cust> v; v.push_back(cust("jim","coe",42)); Cust c("joe","fix",77); v.push_back(c); std::cout << "c: " << c << std::endl; // output c: [77: joe fix] Cust d1"tim"; Cust e1d1; const Cust d2"tim"; Cust e1d2; 217 by IT-communication.com 38

Default Template Arguments template <typename STR2 = std::string> Cust(const std::string& fn, STR2&& ln = "", long i = ) : first(fn), last(std::forward<str2>(ln)), id(i) template <typename STR2 = std::string> Cust(std::string&& fn, STR2&& ln = "", long i = ) : first(std::move(fn)), last(std::forward<str2>(ln)), id(i) ; std::vector<cust> v; v.push_back(cust("tim","coe",42)); Cust c("joe","fix",77); v.push_back(c); Cust d1"tina"; const Cust d2"bill"; Cust e1d1; Cust e2d2; 217 by IT-communication.com 39 If member templates can be used as copy/move constructor or assignment operator, overload first argument instead of using a template parameter. The safest way: Summary Cust(std::string fn, std::string ln = "", long i = ) : first(std::move(fn)), last(std::move(ln)), id(i) ; The common way: Cust(const std::string& fn, const string& ln = "", long i = ) : first(fn), last(ln), id(i) ; The best performing way: Overload only the first argument: template <typename STR2 = std::string> Cust(const std::string& fn, STR2&& ln = "", long i = ) : first(fn), last(std::forward<str2>(ln)), id(i) template <typename STR2 = std::string> Cust(std::string&& fn, STR2&& ln = "", long i = ) : first(std::move(fn)), last(std::forward<str2>(ln)), id(i) ; 217 by IT-communication.com 4

Summary is tricky You can do everything You can even make every mistake We have 17 support now gcc/g++ v7.1 has full language support VS217.x has some support (will grow with updates in 17) Type traits are tricky See " Templates, 2nd ed." will be out in September 217, see www.tmplbook.com 17 is an improvement See "Programming with 17" probably out this year, see/register at: www.cppstd17.com 2 will be an improvement 217 by IT-communication.com 41 Contact Nicolai M. Josuttis www.josuttis.com nico@josuttis.com 217 by IT-communication.com 42