Higher order programming

  • View
    18

  • Download
    0

Embed Size (px)

DESCRIPTION

Higher order programming. Using C++ and boost. C++ concepts. // T must model MyFuncConcept template generic_function(T t) { t.MyFunc(); }. C++ concepts. T is a model of MyFuncConcept if T has a member function called MyFunc which takes no arguments. C++ concepts. - PowerPoint PPT Presentation

Text of Higher order programming

  • Higher order programmingUsing C++ and boost

    johant - En introduktion till ngra vldigt andvndbara bibliotek.

    ven C++, generic programming och STL.

    Bitvis mycket tekniska detaljer - avbryt och frga!

    Tnkt som diskussion

    Kom grna frbi mig och frga saker

  • C++ concepts// T must model MyFuncConcepttemplate generic_function(T t){ t.MyFunc();}

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

  • C++ conceptsstruct MyFuncClass { void MyFunc() {...} };

    { MyFuncClass mfc; generic_function(mfc); // Compiles

    int i; generic_function(i); // Compilation error}

  • C++ example concepts

    ConceptAssumed valid statmentDefault constructibleT t;CopyableT t2(t1);Assignablet1 = t2;Convertible to OtherTypestatic_cast(t);Output streamablestream

  • C++ conceptsAn assumption about a type parameterCompilation error if assumption failsLanguage support for concepts will be added in C++0Xtemplate ...

  • Polymorphism through conceptsCompile-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();...}

  • Sidenote: boost::concept_checkProvide easy to read compilation errorsEarlier compilation errorsHelps writing understandable code

  • boost::concept_check exampletemplate void stable_sort(RandomAccessIter first, RandomAccessIter last) { using namespace boost; function_requires< RandomAccessIteratorConcept >(); typedef typename std::iterator_traits::value_type value_type; function_requires< LessThanComparableConcept >(); ...}

  • Higher order programmingPassing functions as values

    Having values requires a type

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

  • C++ concept of a functorA class which defines operator()

    struct SomeFunctor{void operator()() {...}};

    template void foo(F f){...f();...}

  • C++ concept of a functorSome 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) {...}};

  • Hand made functor examplesCan take various amounts of arguments

    struct MyNullaryFunctor{void operator()();};

    struct MyUnaryFunctor{void operator()(int arg1);};

  • Hand made functor examplesCan hold state

    struct NullaryFunctor{NullaryFunctor(int state);void operator()();private:int iState;};

    Some STL algorithms requires stateless functors

  • Hand made functor examplesCan return a value

    struct SomePredicate{bool operator(int i)();};

  • STL algorithm exampletemplate std::iterator_traits::difference_typestd::count_if(InputIterator first, InputIterator last, Predicate pred)

    InputIterator is a model of the Input Iterator conceptPredicate is a model of the Predicate conceptInputIterator's value type is convertible to Predicate's argument type

  • STL functor examplenamespace {struct MyPredicate{bool operator()(int i) const { return i>=0 && i
  • boost::functionGeneralized callback through functors

    Compatible with free functions, member functions and other functorsAbstracts away callback typeIntuitive semanticsEasy to read syntax

  • boost::function examplevoid free_func(int x);

    {boost::function callback = free_func;

    callback(10);}

  • boost::function examplestruct MyFunctor { void operator()(int x); };

    {boost::function callback = MyFunctor();

    callback(10);}

  • boost::function examplestruct MyClass { void member_func(int x); };

    {// Need an instance to call a member function variableboost::function callback = &MyClass::member_func;

    MyClass my_class;callback(&my_class, 10);}

  • boost::function semantics {boost::function callback; // unitialized...

    if (callback) callback(10);}

  • boost::function usage exampleclass OkCancelDialog {OkCancelDialog(const boost::function& onOk, const boost::function& onCancel);};

  • Recall from RAII presentation

    prepare_something(); possibly_throwing_call_1();possibly_throwing_call_2();

    rollback_preparation();rollback_call_1();

  • Recall from RAII presentationprepare_something();try{possibly_throwing_call_1();try{possibly_throwing_call_2();} catch (...){rollback_call_1();rollback_preparation();throw;}} catch (...){rollback_preparation();throw;}

  • Recall from RAII presentationError-prone to writeDifficult to readDifficult to changePoor scalability

  • Recall from RAII presentationclass ScopeGuard{ ScopeGuard(const boost::function& rollback) : mRollBack(rollback) {}

    ~ScopeGuard() {if (mRollBack) mRollBack(); }

    void Dismiss() {mRollback = boost::function(); }

    private:boost::function mRollback;};

  • Recall from RAII presentationprepare_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();

  • Writing custom made functorsIs boringGenerates a lot of codeTakes some time

  • boost::bindGenerates unnamed functors from:Function pointersMember function pointers Other functors

    Meant to be used as unnamed temporaries

  • boost::bind examplevoid foo (int arg1, int arg2, int arg3) {std::cout
  • boost::bind, whats happening?void foo (int arg1, int arg2, int arg3);

    boost::bind(foo, 10, _1, 30);

    Whats 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;};

  • boost::bind examplenamespace {bool my_pred (int i) { return i>=0 && i
  • boost::bind logical operators

    {std::vector vec = ...;unsigned int single_digits = std::count_if(vec.begin(), vec.end(), _1>=0 && _1

  • boost::bind member functionsstruct X{void SomeFunc(int arg1, int arg2);};

    {std::vector vec;std::for_each(vec.begin(), vec.end(), boost::bind(&X::SomeFunc, _1, 1, 2));}

  • boost::bind nested expressionsstd::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

  • boost::bind semanticsBound 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;};

  • boost::bind referencesvoid foo(const X& arg);

    {X x;boost::bind(foo, boost::cref(x))();}

  • boost::bind and shared_ptrstruct X {void foo() {}};

    {boost::shared_ptr x;boost::bind(&X::foo, x)();}

  • bind&function usageBindPass as unnamed temporaries for templated functionsBind arguments as stateSpecifically bind instances to member functionsReorder arguments

    FunctionPass as arguments for non-templated functionsAbstracts away function typeStore as non-templated variablesCan be uninitialized

  • Combining bind and functionfunction and bind both model the functor conceptBoth are compatible with other functors

    void func(int arg1);

    {boost::function call = boost::bind(func, 1000);}

  • Combining bind and function// Non-templated higher order functionvoid register_callback(boost::function callback);

    void my_callback(int source);

    {register_callback(boost::bind(&my_callback, 10));}

  • Boost lambdaSimilar to bind, larger and more advanced libraryPushes the limits of the C++ language

    using namespace boost;

    std::vector v = ...;std::for_each(v.begin(), v.end(), if_(_1 % 2 == 0)[ cout