90
C++ for C Programmers by Ira Pohl C++ 2011 Standard C++ For C Programmers :2 nd half C++11 feature of the day STL

C++ 2011 Standard - Amazon S3 · C++ for C Programmers by Ira Pohl C++ 2011 Standard ! C++ For C Programmers :2nd half C++11 feature of the day ! STL

Embed Size (px)

Citation preview

C++ for C Programmers by Ira Pohl

C++ 2011 Standard

l  C++ For C Programmers :2nd half l  C++11 feature of the day l  STL

C++ for C Programmers by Ira Pohl

Part I

l  You have completed Part I, and:

l  Know basic C++

l  Have coded both Min Spanning Tree and Dijkstra’s algorithm

l  Followed in my book – if available Ch1-6

C++ for C Programmers by Ira Pohl

Part II

l  More Standard Template Library

l  New features of C++11, such as move semantics, and lambda expressions

l  AI techniques used in implementing the game of Hex

l  Highlight

C++ for C Programmers by Ira Pohl

New in C++11 std

l  Let us introduce new practice and see how it replaces existing practice

l  enum class is a type safe better form of enumeration type

C++ for C Programmers by Ira Pohl

Example :enum class

l  enum class Color{RED, GREEN, BLUE}; l  enum class Stoplight{RED, YELLOW, GREEN};

l  With simple enums these shared enumerators would be ambiguous

l  In C++11 they constitute separate type Stoplight::RED is different in type from Color::RED; both can be used in the same scope

C++ for C Programmers by Ira Pohl

enum class enumerator type

l  The underlying type of enum classes is by default an int; this can be specified to be a different integral type .

l  enum class Color : short {RED, BLUE, GREEN};

l  enum class Identifier : Integral_Type{ enumerator list};

C++ for C Programmers by Ira Pohl

Quiz: Define an enumerator

l  Define a enum class that models three logical values – yes, no, maybe- whose underlying type is unsigned and where yes>maybe>no

l  --- also yes worth 2 maybe’s

C++ for C Programmers by Ira Pohl

Answer

l  enum class WierdLogic :unsigned{ l  NO, l  MAYBE = 5, l  YES = 10 l  }; // a yes is worth 2 maybe’s

C++ for C Programmers by Ira Pohl

Standard Template Library

l  Three Legged Stool l  Containers: Sequence containers

l  vector, deques, list l  Associative containers

l  set,map l  Iterators: input …random l  Algorithms:

l  Non-mutating sequence algorithms : Find, Count l  Mutating Sequence: Copy Random Shuffle, l  Sorting-Related:sort, Merge l  Numeric: accumulate, inner product

C++ for C Programmers by Ira Pohl

Some New Libraries C++11

l  <regex> - regular expression l  <thread> - threading l  <unordered_map> -hash based map l  <array> - fixed size array l  <forward_list> - singly linked list l  And much more …

C++ for C Programmers by Ira Pohl

Quiz:

l  In C

l  A C container is ? l  A C iterator is ? l  A C algorithm is ? l  Generics can be done clumsily with?

C++ for C Programmers by Ira Pohl

Answers:

l  In C

l  A C container is an array such as l  int d[100] l  A C iterator is a pointer int* p = d; l  A C algorithm is ? rand(), sqrt() … l  Generics can be done clumsily with void*

C++ for C Programmers by Ira Pohl

Iterator Categories

l  We have seen input and output iterators l  Must have a single pass algorithm such as find

l  Next up forward, bidirectional, random access

C++ for C Programmers by Ira Pohl

Forward

C++ for C Programmers by Ira Pohl

Iterator-Escher Staircase

C++ for C Programmers by Ira Pohl

C++ Forward Iterator

l  Search forward direction one-by-one. l  The operator ++ is defined ("advance

the iterator") and dereferencing operators * and ->.

l  Iterators may be compared for equality == and != and may be constructed and copy constructed. A canonical algorithm using this iterator is the STL replace algorithm:

C++ for C Programmers by Ira Pohl

replace

l  template<class T> void replace(ForwardIterator first, ForwardIterator last,

const T& x, const T& y);

l  This algorithm replaces occurences of x by y in the specified iterator range.

C++ for C Programmers by Ira Pohl

Square using iterator

l  #include<iostream> #include<iterator> #include<fstream> #include<vector> using namespace std; template<typename ForwardIterator> void square(ForwardIterator first, ForwardIterator last) { for(; first!=last; first++) *first = (*first) * (*first); }

C++ for C Programmers by Ira Pohl

main

l  int main() { ….

square(w.begin(), w.end());

for(auto i: w) // range for

cout << i << "\t"; cout << endl; }

C++ for C Programmers by Ira Pohl

Example: Poker Probability

l  Wish to compute the probability in 5 card stud of making a straight flush

l  Will create abstract data types to have card l  Will use vector and shuffle from STL

C++ for C Programmers by Ira Pohl

Wow A Straight Flush

C++ for C Programmers by Ira Pohl

Quiz:

l  Poker probabilities for 5 card stud

l  Flush is approximately l  A) 1/10, B)1/500 , C) 1/10,000

l  Straight Flush is approximately l  A) 1/700, B)1/7000, C)1/70,000

C++ for C Programmers by Ira Pohl

Some types

l  enum class: short suit{SPADE, HEART, DIAMOND, CLUB};

l  class pips{ l  public: l  pips(int val):v(val){ assert(v>0 && v <14);} l  friend ostream& operator<<(ostream& out, pips p); l  int get_pips(){return v;} l  private: l  int v; l  };

C++ for C Programmers by Ira Pohl

Card type

l  class card l  { l  public: l  card():s(suit::SPADE),v(1){} l  card(suit s, pips v):s(s),v(v){} l  friend ostream& operator<<(ostream& out, card c ); l  suit get_suit(){return s;} l  pips get_pips(){return v;} l  private: l  suit s; l  pips v; l  }; l  ostream& operator<<(ostream& out, card c ){ l  cout << c.v << c.s; //presumes << overloaded for pips and suit l  return out; l  }

C++ for C Programmers by Ira Pohl

Deck – vector of cards

l  void init_deck(vector <card> & d){ l  for(int i = 1; i < 14; ++i){ l  card c(suit::SPADE, i); l  d[i-1] = c; l  } l  for(int i = 1; i < 14; ++i){ l  card c( suit:: HEART, i); l  d[i+12] = c; l  } l  for(int i = 1; i < 14; ++i){ l  card c(suit:: DIAMOND, i); l  d[i+25] = c; l  } l  for(int i = 1; i < 14; ++i){ l  card c(suit:: CLUB, i); l  d[i+38] = c; l  } l  }

C++ for C Programmers by Ira Pohl

C11 auto feature

l  void print (vector <card> & deck) l  { l  for(auto p = deck.begin(); p!= deck.end(); ++p) l  cout << *p; l  cout << endl; l  } l  bool is_flush(vector < card > & hand) l  { l  suit s = hand[0].get_suit(); l  for(auto p = hand.begin() + 1; p!= hand.end(); ++p) l  if (s != p -> get_suit()) l  return false; l  return true; l  }

C++ for C Programmers by Ira Pohl

Quiz

l  Change print() to use range for() statement

C++ for C Programmers by Ira Pohl

Answer:

l  void print (vector <card> & deck) l  { l  for(auto cardval:deck)

§  cout << cardval; l  cout << endl; l  }

C++ for C Programmers by Ira Pohl

straight

l  bool is_straight(vector < card > & hand){ l  int pips_v[5], i = 0; l  for(auto p = hand.begin(); p!= hand.end(); ++p) l  pips_v[i++] = (p -> get_pips()).get_pips(); l  sort(pips_v, pips_v +5); //stl iterator range l  if (pips_v[0] != 1) //non-aces l  return ( pips_v[0] == pips_v[1] -1 && pips_v[1] == pips_v[2] -1 ) l  && ( pips_v[2] == pips_v[3] -1 && pips_v[3] == pips_v[4] -1 ); l  else //aces have a special logic l  return ( pips_v[0] == pips_v[1] -1 && pips_v[1] == pips_v[2] -1 ) l  && ( pips_v[2] == pips_v[3] -1 && pips_v[3] == pips_v[4] -1 ) l  || (pips_v[1] == 10)&&(pips_v[2] == 11)&&(pips_v[3] ==12)&& l  (pips_v[4] == 13); l  }

C++ for C Programmers by Ira Pohl

So straight flush is easy

l  bool is_straight_flush(vector < card > & hand){

l  return is_flush(hand) && is_straight(hand); l  }

C++ for C Programmers by Ira Pohl

Set up simulation

l  int main() l  { l  vector < card > deck(52); l  srand(time(0)); l  init_deck(deck); l  int how_many ; l  int flush_count = 0; l  int str_count = 0; l  int str_flush_count = 0; l  cout << " How Many shuffles?"; l  cin >> how_many;

C++ for C Programmers by Ira Pohl

STL use to run simulation

l  for(int loop = 0; loop < how_many; ++loop){ l  random_shuffle(deck.begin(), deck.end()); //STL algorithm l  vector <card> hand(5); l  int i = 0; l  for( auto p = deck.begin(); i < 5; ++p) l  hand[i++] = *p; l  if (is_flush(hand)) l  flush_count++; l  if (is_straight(hand)) l  str_count++; l  if (is_straight_flush(hand)) l  str_flush_count++ ; l  } l  cout << " Flushes " << flush_count << " out of " << how_many << endl; l  cout << " Straights " << str_count << " out of " << how_many<< endl; l  cout << " Straight Flushes " << str_flush_count << " out of " l  << how_many << endl;

C++ for C Programmers by Ira Pohl

Quiz at home

l  Write is_4of_akind()

l  Write is_straight_flush() for 7 card stud or 5 card draw.

C++ for C Programmers by Ira Pohl

Bidirectional Iterator

l  The bidirectional iterator must allow the elements to be searched in both a forward direction and backward direction.

l  This requires the operation on a forward iterator ++ operator -- ("back up the iterator").

C++ for C Programmers by Ira Pohl

reverse

l  A canonical algorithm using this iterator is the STL reverse() algorithm: template<typename T> void reverse(BidirectionalIterator first, BidirectionalIterator last); This algorithm reverses the elements in the specified iterator range.

C++ for C Programmers by Ira Pohl

How would you write reverse

C++ for C Programmers by Ira Pohl

Move both ends

l  Front++ l  Back—

l  So swap and move would lead to reverse

C++ for C Programmers by Ira Pohl

Palindrome

C++ for C Programmers by Ira Pohl

Palindrome

l  Otto

l  Dalmatian

C++ for C Programmers by Ira Pohl

Palindrome

l  Otto ottO

l  Dalmatian

C++ for C Programmers by Ira Pohl

Palindrome

l  Otto ottO

l  Dalmatian Na it am lad

C++ for C Programmers by Ira Pohl

isPalindrome

l  template<typename Bidirectional> bool isPalindrome(Bidirectional first, Bidirectional last) { while( true ){ last--; if(first == last) //assume >= undefined

break; if(*first != *last)

return false; first++; if(first == last)

break; } return true; }

C++ for C Programmers by Ira Pohl

How it works

l  The algorithm moves forward and backward testing each position for equality.

l  It checks if a value is not equal and returns false.

l  If all values

test as equal then the iterators "meet in the middle" (or pass each other) and it returns true.

l  Compare to how you would do this with a forward only iterator - becomes n*n

C++ for C Programmers by Ira Pohl

Random access Iterator

l  The random access iterator must allow the elements to be randomly searched in fixed time. Think indexed array.

l  This requires effectively being able to add or subtract to an iterator value and retrieve a value from the computed position.

l  It also means that iterator values can be compared for less and greater than as well as equality operators.

C++ for C Programmers by Ira Pohl

Sort() -hoare quicksort

l  A canonical algorithm using this iterator is the STL sort() algorithm: template<class T> void sort(RandomAccessIterator first, RandomAccessIterator last);

C++ for C Programmers by Ira Pohl

Pick an element at random

l  template< typename RandomAccess> RandomAccess pickRandEl( RandomAccess first, RandomAccess last) { ptrdiff_t temp = last-first; return first + rand()%temp; }

C++ for C Programmers by Ira Pohl

ptrdiff_t

l  #include<cstddef> //ptrdiff_t l  ptrdiff_t. type. <cstddef>. Result of pointer

subtraction. This is the type returned by the subtraction operation between two pointers. This is a signed integral type.

C++ for C Programmers by Ira Pohl

use

l  cout << *pickRandEl(w.begin(),w.end());

C++ for C Programmers by Ira Pohl

Standard Template Library

l  Standard template library accepted in July 1994 into C++ ANSI Standard

l  STL library provides containers, iterators and algorithms designed to l  work efficiently l  work parametrically l  work orthogonally

C++ for C Programmers by Ira Pohl

l  Sequence - ordered by sequence of elements

l  Associative - keys for looking up elements

Two Varieties of Containers

vector!list!deque!

set! map! multimap!multiset!

C++ for C Programmers by Ira Pohl

Typical Container Interfaces

l  Constructors l  default constructors, copy constructors

l  Element access l  Element insertion l  Element emplacement -new C++11(&&) l  Element deletion l  Destructor l  Iterators

C++ for C Programmers by Ira Pohl

Overview of Containers

l  Common set of properties l  Constructors and destructors l  Element access, insertion and deletion l  Allocate and manage memory

l  Associated allocator objects

C++ for C Programmers by Ira Pohl

Associative Containers

l  Key based accessible elements

l  Ordering relation Compare l Comparison object for the associative container

set! map! multimap!multiset!

C++ for C Programmers by Ira Pohl

Unordered_map

l  C++11 introduces “hash” based lookup for map and set

l  unordered_map -uses hash lookup l  unordered_set - uses hash lookup

l  Advantage – much of the time O(1) lookup

C++ for C Programmers by Ira Pohl

MAP Program

l  #include <map> l  #include <unordered_map> l  #include <string> l  #include <iostream> l  using namespace std; l  //we will use both types of map

C++ for C Programmers by Ira Pohl

MAP Program l  int main() l  { l  map<unsigned long, string> worker; l  unordered_map<unsigned long, unsigned> payroll; l  unsigned total_pay =0; l  worker[99567800] = "Harold Fish"; l  payroll[99567800] = 67300; l  worker[8567800] = "Phillip Fish"; l  payroll[89567800] = 87300;

C++ for C Programmers by Ira Pohl

MAP

l  Worker links id number to name

l  Payroll links id number to salary

l  Ordinary map red-black tree

l  Unordered map hash

C++ for C Programmers by Ira Pohl

MAP

l  for(auto p = worker.begin(); p != worker.end(); ++p) l  cout << "name " << (*p).second << "\t id no. " << (*p).first << endl;

l  //associate (first, second) l  // (id no, name)

C++ for C Programmers by Ira Pohl

MAP

l  for(auto p = payroll.begin(); p != payroll.end(); ++p) l  total_pay += (*p).second;

l  cout << "payroll totals $"<< total_pay << endl;

C++ for C Programmers by Ira Pohl

STL Algorithms Library

l  Sorting algorithms l  Non-mutating sequence algorithms l  Mutating sequence algorithms l  Numerical algorithms l  Generally use iterators to access containers

instantiated on given type l  Resulting code can be competitive in efficiency with

special purpose codes

C++ for C Programmers by Ira Pohl

Sorting Algorithm Prototypes

l  template<class RandAcc> void sort(RandAcc b, RandAcc e); l  Quicksort algorithm over elements b to e

l 

template<class RandAcc> void stable_sort(RandAcc b, RandAcc e); l  Stable sorting algorithm over elements b to e

l  Elements remain in their relative same position

C++ for C Programmers by Ira Pohl

Non-Mutating Sequence Algorithms

l  Do not modify contents of the containers they work on

l  Typical operation is searching container for particular element and returning its position

C++ for C Programmers by Ira Pohl

Non-mutating Algorithm

l  template<class InputIter, Class T> InputIter find(InputIter b, InputIter e, const T& t)); l  Finds position of t in range b to e

l  template<class InputIter, Class Predicate> InputIter find(InputIter b, InputIter e, Predicate p)); l  Finds position of first element that makes predicate true in

range b to e, otherwise position e returned

C++ for C Programmers by Ira Pohl

Non-mutating Algorithm Prototypes (2 of 2)

l  template<class InputIter, Class Function> void for_each(InputIter b, InputIter e, Function f)); l  Apply f to each value found in range b to e

C++ for C Programmers by Ira Pohl

Example: Algorithm find()

l  int main() // find pos of "hop" { string words[5] = { "my", "hop", "mop", "hope", "cope"}; string* where;

where = find(words, words + 5, "hop"); cout << *++where << endl; //mop sort(words, words + 5); where = find(words, words + 5, "hop"); cout << *++where << endl; //hope }

C++ for C Programmers by Ira Pohl

Lambda Expressions; for_each Expression

l  Derived from Lisp

l  Previously for_each needs a function

l  Will use new C++11 idea – write an unnamed function in place – a lambda expression

C++ for C Programmers by Ira Pohl

Old style for_each()

l  #include <algorithm> l  #include <vector> l  #include <iostream> l  using namespace std;

l  void incr(int &i){static int n = 1; i = n++;} l  void outvec(int i){cout <<i << endl;}

l  int main() l  { l  vector <int> v(6); l  for_each(v.begin(), v.end(), incr ); l  for_each(v.begin(), v.end(), outvec ); l  }

C++ for C Programmers by Ira Pohl

What got printed?

l  vector <int> v(6); l  for_each(v.begin(), v.end(), incr ); l  for_each(v.begin(), v.end(), outvec ); l  }

C++ for C Programmers by Ira Pohl

Answer

l  Static keeps value on exit , so l  1 l  2 l  3 l  4 l  5 l  6

C++ for C Programmers by Ira Pohl

Lambda C++11

l  Taken from LISP

l  Unnamed function l  [](int i){cout <<i << endl;} l  //goes where the function object is required

C++ for C Programmers by Ira Pohl

returns Lambda C++11

l  [] (int n) { return n * 5.5; }//double l  // deduces the return value –no return void l  [] (int n) -> int { return ++n; } //explicit

l  Read wikipedia about Lambda

C++ for C Programmers by Ira Pohl

Mutating Function

l  template<class InputIter, class OutputIter> OutputIter copy(InputIter b1, InputIter e1, OutputIter b2); l  Copying algorithm over elements b1 to e1

l  Copy is placed starting at b2 l  Position returned is end of copy

C++ for C Programmers by Ira Pohl

Suggested work

l  Write a small program with vectors that tests using copy()

C++ for C Programmers by Ira Pohl

Numerical Algorithms

l  Sums l  Inner product l  Adjacent difference l  Numerical Algorithm functions behave as

expected on numerical types where + and * are defined

C++ for C Programmers by Ira Pohl

Numerical Algorithm Program

l  int main() { double v1[3] = { 1.0, 2.5, 4.6 }, v2[3] = { 1.0, 2.0, -3.5 }; double sum, inner_p;

l  sum = accumulate(v1, v1 + 3, 0.0); inner_p = inner_product(v1, v1 + 3, v2, 0.0); cout << "sum = " << sum << ", product = " << inner_p << endl; }

C++ for C Programmers by Ira Pohl

Numerical Algorithm Prototypes (1 of 2)

l  template<class InputIter, class T> T accumulate(InputIter b, InputIter e, T t); l  Standard accumulation algorithm whose sum is

initially t l  Successive elements from the range b to e are added

to sum

C++ for C Programmers by Ira Pohl

Numerical Algorithm Prototypes (2 of 2)

l  template<class InputIter, class T, class BinOp> T accumulate(InputIter b, InputIter e, T t, BinOp bop); l  Accumulation whose sum is initially t

l  Successive elements from range b to e are summed with sum = bop(sum, element)

C++ for C Programmers by Ira Pohl

Function Objects

l  Useful to have function objects to further leverage STL library l  Numerical functions have built-in meaning using + or

*, as well as user-provided binary operators which could be passed in

l  Defined function objects can be found in function.h or built

l  Function objects are classes that have operator() defined l  Inlined, compiled producing efficient object code"

C++ for C Programmers by Ira Pohl

Function Object for minus<int>

l  int main() { double v1[3] = {1.0, 2.5, 4.6}, sum; sum = accumulate(v1, v1 + 3, 0.0, minus<int>()); cout << "sum = " << sum << endl;

l  //sum = -7 } l  Accumulation using integer minus for binary

operation over the array v1[]

C++ for C Programmers by Ira Pohl

Generator Object and Integration

l  // The function is represented in class gen

l  class gen { // generator for integrated function l  public: l  gen(double x_zero, double increment) l  : x(x_zero), incr(increment) { } l  double operator()() { x += incr; return x * x; } l  private: l  double x, incr; l  };

C++ for C Programmers by Ira Pohl

integrate

l  double integrate(gen g, int n) l  // integrate on (0,1) l  { l  vector<double> fx(n);

l  generate(fx.begin(), fx.end(), g); l  return l  (accumulate(fx.begin(), fx.end(), 0.0) / n); l  }

C++ for C Programmers by Ira Pohl

End of code

l  int main() l  { l  const int n = 10000;

l  gen g(0.0, 1.0/n); l  cout << "integration program x**2" << endl; l  cout << integrate(g, n) << endl; l  }

C++ for C Programmers by Ira Pohl

Defined Function Object Classes

l  Arithmetic objects

l  Comparison objects

l  Logical objects

C++ for C Programmers by Ira Pohl

Arithmetic Objects (1 of 2)

l  template <class T> struct plus<T> l  Adds two operands of type T

l  template <class T> struct minus<T> l  Subtracts two operands of type T

l  template <class T> struct times<T> l  Multiplies two operands of type T

C++ for C Programmers by Ira Pohl

Arithmetic Objects (2 of 2)

l  template <class T> struct divides<T> l  Divides two operands of type T

l  template <class T> struct modulus<T> l  Modulus (%) for two operands of type T

l  template <class T> struct negate<T> l  Unary minus for one argument of type T

C++ for C Programmers by Ira Pohl

Function Adapters

l  Creation of function objects using adaption

l  Negators for negating predicate objects

l  Binders for binding a function argument

l  Adapters for pointer to function

C++ for C Programmers by Ira Pohl

Use of Function Adapter bind2nd (1 of 2)

l  template <class ForwIter> void print(ForwIter first, ForwIter last,

l  const char* title) { cout << title << endl; while( first != last) cout << *first++ << '\t'; cout << endl; }

C++ for C Programmers by Ira Pohl

Use of Function Adapter bind2nd (2 of 2) l  // use a binder function bind2nd to transform initial sequence of //

values to these values doubled l  int main()

{ int data[3] = { 9, 10, 11}; print(data, data + 3, "Original values"); transform(data, data + 3, data, bind2nd(times<int>(), 2)); print(data, data + 3, "New values"); }

C++ for C Programmers by Ira Pohl

STL Based on Templates

l  Key to understanding STL is to use iterator logic

l  When extending STL keep consistent with existing libraries

l  Generality and genericity are not enough:

It’s not STL if it isn’t efficient

C++ for C Programmers by Ira Pohl

Next Time:

l  How to play Tic-Tac-Toe

l  The game of Hex – term assignment