Title: Higher order programming
1Higher order programming
2C concepts
- // T must model MyFuncConcept
- templateltclass Tgt
- generic_function(T t)
-
- t.MyFunc()
3C concepts
- T is a model of MyFuncConcept if T has a member
function called MyFunc which takes no arguments
4C concepts
- struct MyFuncClass void MyFunc() ...
-
- MyFuncClass mfc
- generic_function(mfc) // Compiles
- int i
- generic_function(i) // Compilation error
5C example concepts
Concept Assumed valid statment
Default constructible T t
Copyable T t2(t1)
Assignable t1 t2
Convertible to OtherType static_castltOtherTypegt(t)
Output streamable stream ltlt t
6C concepts
- An assumption about a type parameter
- Compilation error if assumption fails
- Language support for concepts will be added in
C0X - template ltDefaultConstructible Tgt ...
7Polymorphism through concepts
- Compile-time polymorphism through impicit
interfaces - templateltclass Tgt void foo(T t)
-
- ...
- t.bar()
- ...
-
- Run-time polymorphism through explicit interfaces
- class FooType virtual void bar() 0
- void foo(FooType t)
-
- ...
- t.bar()
- ...
-
8Sidenote boostconcept_check
- Provide easy to read compilation errors
- Earlier compilation errors
- Helps writing understandable code
9boostconcept_check example
- template ltclass RandomAccessItergt
- void stable_sort(RandomAccessIter first,
- RandomAccessIter last)
-
- using namespace boost
- function_requireslt RandomAccessIteratorConceptltR
andomAccessItergt gt() - typedef typename stditerator_traitsltRandomAcce
ssItergtvalue_type - value_type
- function_requireslt LessThanComparableConceptltval
ue_typegt gt() - ...
-
10Higher order programming
- Passing functions as values
- Having values requires a type
11C function pointers
- Unintuitive syntax
- Casting between member function pointers
problematic - Pointers to virtual functions problematic
- Different compilers behave differentally
12C concept of a functor
- A class which defines operator()
- struct SomeFunctor
-
- void operator()() ...
-
- template ltclass Fgt
- void foo(F f)
-
- ...
- f()
- ...
13C concept of a functor
- Some STL algorithms also require internal
typedefs for - return_type, first_argument_type,
second_argument_type - struct SomeFunctor
-
- typedef bool return_type
- typedef int first_argument_type
- bool operator()(int x) ...
14Hand made functor examples
- Can take various amounts of arguments
- struct MyNullaryFunctor
-
- void operator()()
-
- struct MyUnaryFunctor
-
- void operator()(int arg1)
15Hand made functor examples
- Can hold state
- struct NullaryFunctor
-
- NullaryFunctor(int state)
- void operator()()
- private
- int iState
-
- Some STL algorithms requires stateless functors
16Hand made functor examples
- Can return a value
- struct SomePredicate
-
- bool operator(int i)()
-
17STL algorithm example
- template ltclass InputIterator, class Predicategt
- stditerator_traitsltInputIteratorgtdifference_ty
pe - stdcount_if(InputIterator first, InputIterator
last, Predicate pred) - InputIterator is a model of the Input Iterator
concept - Predicate is a model of the Predicate concept
- InputIterator's value type is convertible to
Predicate's argument type
18STL functor example
- namespace
-
- struct MyPredicate
-
- bool operator()(int i) const return igt0
ilt9 -
-
-
- stdvectorltintgt vec ...
-
- unsigned int single_digits stdcount_if(vec.be
gin(), -
vec.end(), -
MyPredicate())
19boostfunction
- Generalized callback through functors
- Compatible with free functions, member functions
and other functors - Abstracts away callback type
- Intuitive semantics
- Easy to read syntax
20boostfunction example
- void free_func(int x)
-
- boostfunctionltvoid(int x)gt callback
free_func - callback(10)
-
21boostfunction example
- struct MyFunctor void operator()(int x)
-
- boostfunctionltvoid(int x)gt callback
MyFunctor() - callback(10)
-
22boostfunction example
- struct MyClass void member_func(int x)
-
- // Need an instance to call a member function
variable - boostfunctionltvoid(MyClass, int x)gt callback
- MyClassmember_func
- MyClass my_class
- callback(my_class, 10)
-
23boostfunction semantics
-
- boostfunctionltvoid(int x)gt callback //
unitialized -
- ...
- if (callback) callback(10)
-
24boostfunction usage example
- class OkCancelDialog
-
- OkCancelDialog(const boostfunctionltvoid()gt
onOk, - const boostfunctionltvoid()gt
onCancel) -
25Recall from RAII presentation
- prepare_something()
- possibly_throwing_call_1()
- possibly_throwing_call_2()
- rollback_preparation()
- rollback_call_1()
26Recall from RAII presentation
- prepare_something()
- try
-
- possibly_throwing_call_1()
- try
-
- possibly_throwing_call_2()
-
- catch (...)
-
- rollback_call_1()
- rollback_preparation()
- throw
-
-
- catch (...)
-
- rollback_preparation()
- throw
27Recall from RAII presentation
- Error-prone to write
- Difficult to read
- Difficult to change
- Poor scalability
28Recall from RAII presentation
- class ScopeGuard
-
- ScopeGuard(const boostfunctionltvoid()gt
rollback) - mRollBack(rollback)
- ScopeGuard()
-
- if (mRollBack) mRollBack()
-
- void Dismiss()
-
- mRollback boostfunctionltvoid()gt()
-
- private
- boostfunctionltvoid()gt mRollback
29Recall from RAII presentation
- prepare_something()
- ScopeGuard preparation_guard(rollback_preparation)
- possibly_throwing_call_1()
- ScopeGuard call_1_guard(rollback_call_1)
- possibly_throwing_call_2()
- // Commit
- preparation_guard.Dismiss()
- call_1_guard.Dismiss()
30Writing custom made functors
- Is boring
- Generates a lot of code
- Takes some time
31boostbind
- Generates unnamed functors from
- Function pointers
- Member function pointers
- Other functors
- Meant to be used as unnamed temporaries
32boostbind example
- void foo (int arg1, int arg2, int arg3)
-
- stdcout ltlt arg1 ltlt ltlt arg2 ltlt ltlt arg3
ltlt stdendl -
-
- boostbind(foo, _1, _2, _3) (1, 2, 3)
- boostbind(foo, _3, _2, _1) (1, 2, 3)
- boostbind(foo, _1, _1, _1) (20)
- boostbind(foo, _3, _3, _3) (10, 20, 30)
- boostbind(foo, 1, 2, 3) ()
- boostbind(foo, 1, _1, 1) (1, 2, 3)
-
33boostbind, whats happening?
- void foo (int arg1, int arg2, int arg3)
- boostbind(foo, 10, _1, 30)
- Whats the return type of the bind expression?
- struct some_super_strange_type_with_loads_of_templ
ates -
- void operator(int x) foo(iArg1, x, iArg3)
- int iArg1, iArg3
-
34boostbind example
- namespace
- bool my_pred (int i) return igt0 ilt9
-
-
- stdvectorltintgt vec ...
-
- unsigned int single_digits
- stdcount_if(vec.begin(), vec.end(),
boostbind(my_pred, _1))
35boostbind logical operators
-
- stdvectorltintgt vec ...
-
- unsigned int single_digits
- stdcount_if(vec.begin(), vec.end(), _1gt0
_1lt9)
36boostbind member functions
- struct X
-
- void SomeFunc(int arg1, int arg2)
-
-
- stdvectorltXgt vec
- stdfor_each(vec.begin(), vec.end(),
- boostbind(XSomeFunc, _1, 1, 2))
37boostbind nested expressions
- stdstring f(stdstring const x) return
"f(" x ")" - stdstring g(stdstring const x) return
"g(" x ")" - stdstring h(stdstring const x, stdstring
const y) - return "h(" x ", " y ")"
- stdstring k() return "k()"
- templateltclass Fgt void test(F f) stdcout ltlt
f("x", "y") ltlt '\n' -
- using namespace boost
- test( bind(f, bind(g, _1)) )
- test( bind(f, bind(h, _1, _2)) )
- test( bind(h, bind(f, _1), bind(g, _1)) )
- test( bind(h, bind(f, _1), bind(g, _2)) )
- test( bind(f, bind(k)) )
-
38boostbind semantics
- Bound values are stored by value!
- struct some_super_strange_type_with_loads_of_templ
ates -
- void operator(int x) foo(iArg1, x, iArg3)
- int iArg1, iArg3
-
39boostbind references
- void foo(const X arg)
-
- X x
- boostbind(foo, boostcref(x))()
40boostbind and shared_ptr
- struct X
-
- void foo()
-
-
- boostshared_ptrltXgt x
- boostbind(Xfoo, x)()
41bindfunction usage
- Bind
- Pass as unnamed temporaries for templated
functions - Bind arguments as state
- Specifically bind instances to member functions
- Reorder arguments
- Function
- Pass as arguments for non-templated functions
- Abstracts away function type
- Store as non-templated variables
- Can be uninitialized
42Combining bind and function
- function and bind both model the functor concept
- Both are compatible with other functors
- void func(int arg1)
-
- boostfunctionltvoid()gt call boostbind(func,
1000)
43Combining bind and function
- // Non-templated higher order function
- void register_callback(boostfunctionltvoid()gt
callback) - void my_callback(int source)
-
- register_callback(boostbind(my_callback,
10))
44Boost lambda
- Similar to bind, larger and more advanced library
- Pushes the limits of the C language
- using namespace boost
- stdvectorltintgt v ...
- stdfor_each(v.begin(), v.end(), if_(_1 2
0) cout ltlt _1 ) - int a510 int i
- stdfor_each(a, a5, for_loop(var(i)0,
var(i)lt10, var(i), - _1var(i) 1))
- stdfor_each(v.begin(), v.end(),
- (
- switch_statement( _1,
- case_statementlt0gt(stdcout ltlt
constant("zero")),
case_statementlt1gt(stdcout ltlt constant("one")),
- default_statement(cout
ltlt constant("other ") ltlt _1) ), - cout ltlt constant("\n") )
- )