Function
========



Callable concept:




#include <functional>

template < class >
class function;

template < class R, class... Args >
class function< R(Args...) >


General-purpose plymorphic function wrapper. Store, copy and invoke Callable.
Copy constructible, and copy assignable.

The callable can be:
	function,
	lambda expr,
	bind expr,
	function object,
	pointer to member function
	pointer to data member

target -- the stored callable.
empty -- no target

If invoked on empty functional: std::bad_function_call is thrown.


Invoke
======


template< class F, class... ArgTypes>
std::result_of_t<F&&(ArgTypes&&...)> invoke(F&& f, ArgTypes&&... args);


INVOKE( f, std::declval<ArgTypes>()..., R)


INVOKE(f, t1, t2, ..., tN) === (t1.*f)(t2, ..., tN)        // pointer to member
INVOKE(f, t1, t2, ..., tN) === (t1.get().*f)(t2, ..., tN)  //   ref wrapper
INVOKE(f, t1, t2, ..., tN) === ((*t1).*f)(t2, ..., tN)     //   +ptr to obj
INVOKE(f, t1)              ===  t1.*f                      // data member
INVOKE(f, t1)              ===  t1.get().*f                //   ref wrapper 
INVOKE(f, t1)              === (*t1).*f                    // function object  
INVOKE(f, t1, t2, ..., tN) === (t1, t2, ..., tN)           //   funct. obj.   






Member types
=============

result_type

argument_type        (until C++17)
first_argument_type  (until C++17)
second_argument_type (until C++17)



Member functions
================

operator=
swap
assign (until C++17)
operator bool
operator()

target_type   (returns typed of target)
target        (pointer to target)


Global functions
================
std::swap
operator==       compares std::function with nullptr
operator!=




#include <functional>
#include <iostream>

struct Foo
{
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};

void print_num(int i)
{
    std::cout << i << '\n';
}

struct PrintNum
{
    void operator()(int i) const
    {
        std::cout << i << '\n';
    }
};

int main()
{
    // store a free function
    std::function<void(int)> glob = print_num;
    glob(-9);

    // store a lambda
    std::function<void()> lambda = []() { print_num(42); };
    lambda();

    // store the result of a call to std::bind
    std::function<void()> bind_glob = std::bind(print_num, 99);
    bind_glob();

    // store a call to a member function
    std::function<void(const Foo&, int)> mem_fun = &Foo::print_add;
    const Foo foo(555);
    mem_fun(foo, 1);

    // store a call to a data member accessor
    std::function<int(Foo const&)> mem_data = &Foo::num_;
    std::cout << "num_: " << mem_data(foo) << '\n';

    // store a call to a member function and object
    using std::placeholders::_1;
    std::function<void(int)> mem_fun_obj = std::bind( &Foo::print_add, foo, _1 );
    mem_fun_obj(2);

    // store a call to a member function and object ptr
    std::function<void(int)> mem_fun_obj_ptr = std::bind( &Foo::print_add, &foo, _1 );
    mem_fun_obj_ptr(3);

    // store a call to a function object
    std::function<void(int)> fun_obj = PrintNum();
    fun_obj(18);
}



Bind
====



template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );

template< class R, class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );


Creates a forward call wrapper for f. Calling this wrapper is
like calling f with some arguments bound to args. Unbound parameters
are replaced by placeholders: _1, _2, _3, ... from std::placeholders.



#include <random>
#include <iostream>
#include <memory>
#include <functional>

void f(int n1, int n2, int n3, const int& n4, int n5)
{
    std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}

int g(int n1)
{
    return n1;
}

struct Foo
{
    void print_sum(int n1, int n2)
    {
        std::cout << n1 + n2 << '\n';
    }
    int data = 10;
};

int main()
{
    using namespace std::placeholders;  // for _1, _2, _3...

    // demonstrates argument reordering and pass-by-reference
    int n = 7;
    // (_1 and _2 are from std::placeholders, and represent future
    // arguments that will be passed to f1)
    auto f1 = std::bind(f, _2, _1, 42, std::cref(n), n);
    n = 10;
    f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
                    // makes a call to f(2, 1, 42, n, 7)

    // nested bind subexpressions share the placeholders
    auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
    f2(10, 11, 12);

    // common use case: binding a RNG with a distribution
    std::default_random_engine e;
    std::uniform_int_distribution<> d(0, 10);
    std::function<int()> rnd = std::bind(d, e); // a copy of e is stored in rnd
    for(int n=0; n<10; ++n)
        std::cout << rnd() << ' ';
    std::cout << '\n';

    // bind to a pointer to member function
    Foo foo;
    auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
    f3(5);

    // bind to a pointer to data member
    auto f4 = std::bind(&Foo::data, _1);
    std::cout << f4(foo) << '\n';

    // smart pointers can be used to call members of the referenced objects, too
    std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
              << f4(std::make_unique<Foo>(foo)) << '\n';
}
Output:

2 1 42 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10



Function example
================


based on http://www.drdobbs.com/cpp/efficient-use-of-lambda-expressions-and/232500059

std::count_if(v.begin(), v.end(), is_multiple_of(n));


class is_multiple_of
{
public:
  typedef bool result_type;     // These two typedefs are recommended but not
  typedef int argument_type;    // strictly required. More details to come.
  is_multiple_of(int n) : n(n) {}
  bool operator()(int i) const { return i%n == 0; }
private:
  const int n;
};



with lambda:

std::count_if(v.begin(), v.end(), [n](int i){return i%n == 0;} );




Find the root of f, i.e. return x where f(x) = 0

template <typename T>
double find_root( const T& f);  // must be a template, we do not know f


but there are issues with templates:
  - code must be exposed in header file
  - increased compilation time
  - can not be virtual

how to make find_root non-template?


double find_root( const ?& f); // what is ?


try decltype and auto:

  auto f = [](double x) { ... };
  typedef decltype(f) function_t;

unfortunately, function_t has the same scope as the lambda, we cannot use
in a different source as parameter of find_root(const function_t&)


double find_root(std::function<double(double)> const& f);


Cost
====

1. Constructor takes a functor object by value -> copy.
   Forwards the copy to a number of helper functions -> further copies
     e.g. MSVC and gcclib makes 4, Boost makes 7 copies!

2. Functor's size. The std::function stores the functor in a data member,
   Standard recommends small object optimization, but as the size is
   unknown until construction -> may be created in the heap
   if f is bigger than 12bytes (MSVC), 16bytes (gcclib) or 24bytes (Boost)


Using std::reference_wrapper we can avoid ccopying.


is_multiple_of f(n);
std::count_if(v.begin(), v.end(), std::cref(f));


auto f([n](int i){return i%n == 0;});
std::count_if(v.begin(), v.end(), std::cref(f));

(Not working in Boost, should work in MSVC after 2013, works in gcclib.)



Difference between lambda and functor
======================================

Functor defines member types return_type and argument_type, lambda is not.


std::not1([n](int i){ return i%n == 0; }); // syntax error: 
                                           // not1 requires argument_type

std::not1(is_multiple_of(n));              // works


auto f1([n](int i){return i%n == 0;});     // ok: std::function wrapes lambda
std::function<bool(int)> f(std::cref(f1));
std::count_if(v.begin(), v.end(), f);



Decrease size
=============

double a;
double b;
// ...
[a, b](double x){ return a * x + b; };   // ~16 bytes


double a;
double b;
// ...
struct {
    const double& a;
    const double& b;
} p = { a, b };

[&p](double x){ return p.a * x + p.b; };  // ~8 byte