Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ closure and std::function

I'm trying to figure out what goes on under the hood of std::function when used in combination with closures. I'm not able to wrap my head around it yet, for example: what constructor is being called? Can anybody post a working example of a minimalistic drop in replacement of std::function that supports the functionality needed in the following example?

#include <functional>

int main(int argc, char* argv[])
{
    int mybool = 5;

    auto foo = [&] (int arg) {
        return mybool * arg;
    };

    std::function<int(int)> foo2 = foo;

    int result = foo2(42);

    return 0;
}
like image 796
Corno Avatar asked Oct 17 '13 09:10

Corno


People also ask

What is closure C++?

According to the definition of closure, “In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions”.

Does C support closure?

Although C was created two decades after Lisp, it nonetheless lacks support for closures.

What is the point of std :: function?

Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.

What is object closure explain with suitable example in C++?

C++ enables defining function objects by overloading operator() . These objects behave somewhat like functions in a functional programming language. ... A C++ closure may capture its context either by storing copies of the accessed variables as members of the closure object or by reference.


1 Answers

Here's the minimalistic example:

template <class F>
struct Decomposer;

template <class R, class A>
struct Decomposer<R (A)>
{
  typedef R return_type;
  typedef A argument_type;
};


template <class F>
struct my_function
{
  typedef typename Decomposer<F>::return_type return_type;
  typedef typename Decomposer<F>::argument_type argument_type;

  return_type operator() (argument_type arg) const {
    return (*impl)(arg);
  }

  template <class From>
  my_function(From &&from)
  {
    struct ConcreteImpl : Impl
    {
      typename std::remove_reference<From>::type functor;
      ConcreteImpl(From &&functor) : functor(std::forward<From>(functor)) {}
      virtual return_type operator() (argument_type arg) const override
      {
        return functor(arg);
      }
    };
    impl.reset(new ConcreteImpl(std::forward<From>(from)));
  }

private:
  struct Impl {
    virtual ~Impl() {}
    virtual return_type operator() (argument_type arg) const = 0;
  };

  std::unique_ptr<Impl> impl;
};

The core idea is to use type erasure to store the actual closure without knowing its type: see the virtual Impl::operator() and locally-defined type-specific holder ConcreteImpl.

Live example

like image 187
Angew is no longer proud of SO Avatar answered Oct 04 '22 20:10

Angew is no longer proud of SO