Presentation is loading. Please wait.

Presentation is loading. Please wait.

Higher order programming Using C++ and boost. C++ concepts // T must model MyFuncConcept template generic_function(T t) { t.MyFunc(); }

Similar presentations


Presentation on theme: "Higher order programming Using C++ and boost. C++ concepts // T must model MyFuncConcept template generic_function(T t) { t.MyFunc(); }"— Presentation transcript:

1 Higher order programming Using C++ and boost

2 C++ concepts // T must model MyFuncConcept template generic_function(T t) { t.MyFunc(); }

3 C++ concepts T is a model of MyFuncConcept if T has a member function called MyFunc which takes no arguments

4 C++ concepts struct MyFuncClass { void MyFunc() {...} }; { MyFuncClass mfc; generic_function(mfc); // Compiles int i; generic_function(i); // Compilation error }

5 C++ example concepts ConceptAssumed valid statment Default constructibleT t; CopyableT t2(t1); Assignablet1 = t2; Convertible to OtherTypestatic_cast (t); Output streamablestream << t;

6 C++ concepts An assumption about a type parameter Compilation error if assumption fails Language support for concepts will be added in C++0X template...

7 Polymorphism through concepts Compile-time polymorphism through ”impicit interfaces” template void foo(T& t) {... t.bar();... } Run-time polymorphism through explicit interfaces class FooType { virtual void bar() = 0; }; void foo(FooType& t) {... t.bar();... }

8 Sidenote: boost::concept_check Provide easy to read compilation errors Earlier compilation errors Helps writing understandable code

9 boost::concept_check example template void stable_sort(RandomAccessIter first, RandomAccessIter last) { using namespace boost; function_requires >(); typedef typename std::iterator_traits ::value_type value_type; function_requires >();... }

10 Higher order programming Passing functions as values Having values requires a type

11 C++ function pointers Unintuitive syntax Casting between member function pointers problematic Pointers to virtual functions problematic Different compilers behave differentally

12 C++ concept of a functor A class which defines operator() struct SomeFunctor { void operator()() {...} }; template void foo(F f) {... f();... }

13 C++ 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) {...} };

14 Hand made functor examples Can take various amounts of arguments struct MyNullaryFunctor { void operator()(); }; struct MyUnaryFunctor { void operator()(int arg1); };

15 Hand made functor examples Can hold state struct NullaryFunctor { NullaryFunctor(int state); void operator()(); private: int iState; }; Some STL algorithms requires stateless functors

16 Hand made functor examples Can return a value struct SomePredicate { bool operator(int i)(); };

17 STL algorithm example template std::iterator_traits ::difference_type std::count_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

18 STL functor example namespace { struct MyPredicate { bool operator()(int i) const { return i>=0 && i<=9; } }; } { std::vector vec =...; unsigned int single_digits = std::count_if(vec.begin(), vec.end(), MyPredicate()); }

19 boost::function Generalized callback through functors Compatible with free functions, member functions and other functors Abstracts away callback type Intuitive semantics Easy to read syntax

20 boost::function example void free_func(int x); { boost::function callback = free_func; callback(10); }

21 boost::function example struct MyFunctor { void operator()(int x); }; { boost::function callback = MyFunctor(); callback(10); }

22 boost::function example struct MyClass { void member_func(int x); }; { // Need an instance to call a member function variable boost::function callback = &MyClass::member_func; MyClass my_class; callback(&my_class, 10); }

23 boost::function semantics { boost::function callback; // unitialized... if (callback) callback(10); }

24 boost::function usage example class OkCancelDialog { OkCancelDialog(const boost::function & onOk, const boost::function & onCancel); };

25 Recall from RAII presentation prepare_something(); possibly_throwing_call_1(); possibly_throwing_call_2(); rollback_preparation(); rollback_call_1();

26 Recall 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; }

27 Recall from RAII presentation Error-prone to write Difficult to read Difficult to change Poor scalability

28 Recall from RAII presentation class ScopeGuard { ScopeGuard(const boost::function & rollback) : mRollBack(rollback) {} ~ScopeGuard() { if (mRollBack) mRollBack(); } void Dismiss() { mRollback = boost::function (); } private: boost::function mRollback; };

29 Recall 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();

30 Writing custom made functors Is boring Generates a lot of code Takes some time

31 boost::bind Generates unnamed functors from: Function pointers Member function pointers Other functors Meant to be used as unnamed temporaries

32 boost::bind example void foo (int arg1, int arg2, int arg3) { std::cout << arg1 << ” ” << arg2 << ” ” << arg3 << std::endl; } { boost::bind(foo, _1, _2, _3) (1, 2, 3); boost::bind(foo, _3, _2, _1) (1, 2, 3); boost::bind(foo, _1, _1, _1) (20); boost::bind(foo, _3, _3, _3) (10, 20, 30); boost::bind(foo, 1, 2, 3) (); boost::bind(foo, 1, _1, 1) (1, 2, 3); }

33 boost::bind, what’s happening? void foo (int arg1, int arg2, int arg3); boost::bind(foo, 10, _1, 30); What’s the return type of the bind expression? struct some_super_strange_type_with_loads_of_templates { void operator(int x) { foo(iArg1, x, iArg3); } int iArg1, iArg3; };

34 boost::bind example namespace { bool my_pred (int i) { return i>=0 && i<=9; } } { std::vector vec =...; unsigned int single_digits = std::count_if(vec.begin(), vec.end(), boost::bind(my_pred, _1)); }

35 boost::bind logical operators { std::vector vec =...; unsigned int single_digits = std::count_if(vec.begin(), vec.end(), _1>=0 && _1<=9); }

36 boost::bind member functions struct X { void SomeFunc(int arg1, int arg2); }; { std::vector vec; std::for_each(vec.begin(), vec.end(), boost::bind(&X::SomeFunc, _1, 1, 2)); }

37 boost::bind nested expressions std::string f(std::string const & x) { return "f(" + x + ")"; } std::string g(std::string const & x) { return "g(" + x + ")"; } std::string h(std::string const & x, std::string const & y) { return "h(" + x + ", " + y + ")"; } std::string k() { return "k()"; } template void test(F f) { std::cout << f("x", "y") << '\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)) ); }

38 boost::bind semantics Bound values are stored by value! struct some_super_strange_type_with_loads_of_templates { void operator(int x) { foo(iArg1, x, iArg3); } int iArg1, iArg3; };

39 boost::bind references void foo(const X& arg); { X x; boost::bind(foo, boost::cref(x))(); }

40 boost::bind and shared_ptr struct X { void foo() {} }; { boost::shared_ptr x; boost::bind(&X::foo, x)(); }

41 bind&function 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

42 Combining bind and function function and bind both model the functor concept Both are compatible with other functors void func(int arg1); { boost::function call = boost::bind(func, 1000); }

43 Combining bind and function // Non-templated higher order function void register_callback(boost::function callback); void my_callback(int source); { register_callback(boost::bind(&my_callback, 10)); }

44 Boost lambda Similar to bind, larger and more advanced library Pushes the limits of the C++ language using namespace boost; std::vector v =...; std::for_each(v.begin(), v.end(), if_(_1 % 2 == 0)[ cout << _1 ]); int a[5][10]; int i; std::for_each(a, a+5, for_loop(var(i)=0, var(i)<10, ++var(i), _1[var(i)] += 1)); std::for_each(v.begin(), v.end(), ( switch_statement( _1, case_statement (std::cout (std::cout << constant("one")), default_statement(cout << constant("other: ") << _1) ), cout << constant("\n") ) );


Download ppt "Higher order programming Using C++ and boost. C++ concepts // T must model MyFuncConcept template generic_function(T t) { t.MyFunc(); }"

Similar presentations


Ads by Google