On 14.01.2012 21:42, K. Frank wrote:
>
> I'm looking for some insight into how an assignment such as:
>
> std::function<int, (int, int)> f = [z](int x, int y){ return x + y
> + z; };
>
> actually works under the hood.
Well, disregarding "actually", here's one possibility for your specific
example:
<code>
#include <iostream>
#include <vector>
#include <memory> // std::shared_ptr
class WrapperBase
{
public:
virtual ~WrapperBase() {}
};
template< class Functor >
class Wrapped
: public WrapperBase
{
public:
Functor f;
Wrapped( Functor const& _f ): f( _f ) {}
};
class MyFunc
{
private:
typedef int (*InvokerFunc)( void*, int, int );
std::shared_ptr< WrapperBase > pFunc_;
InvokerFunc invoker_;
template< class Functor >
static int invoke( void* pF, int x, int y )
{
return (reinterpret_cast< Wrapped< Functor>* >( pF )->f)( x, y );
}
public:
template< class Functor >
MyFunc( Functor const& f )
: pFunc_( new Wrapped< Functor >( f ) )
, invoker_( &invoke< Functor > )
{}
int operator()( int x, int y ) const
{
return invoker_( pFunc_.get(), x, y );
}
};
int main()
{
using namespace std;
MyFunc f = []( int x, int y ) -> int { return x*y; };
cout << f( 6, 7 ) << endl;
}
</code>
The technique used for the invoker function is called "type erasure",
and I believe it was developed (by the Boost guys) for just this
purpose, namely for the implementation of boost::function.
Cheers & hth.,
- Alf