Adding support for non-member functions to our delegate

Finally, we need to modify the delegate to add support for non-member functions. Check out this example:

bool attack(int x, int y)
{
return x == 42 && y == 42 ? true : false;
}

To do this, we simply need to add another wrapper as follows:

template<
typename RET,
typename... ARGS
>
class fun_wrapper :
public base<RET, ARGS...>
{
RET (*m_func)(ARGS...);

public:

fun_wrapper(RET (*func)(ARGS...)) :
m_func{func}
{ }

RET func(ARGS... args) override
{
return m_func(args...);
}
};

As shown in the preceding, as with our original wrapper, we store a pointer to the function we wish to call, but in this case, we do not need to store a pointer to an object as there is no object (as this is a  non-member function wrapper). To use this new wrapper, we must add another delegate constructor as follows:

    delegate(RET (func)(ARGS...)) :
m_wrapper{
std::make_unique<fun_wrapper<RET, ARGS...>>(func)
}
{ }

This means we must also provide another user-defined type deduction guide as follows:

template<
typename RET,
typename... ARGS
>
delegate(RET(*)(ARGS...)) -> delegate<RET(ARGS...)>;

With all of the modifications, we are finally able to use our delegate as defined at the beginning of this recipe:

int main(void)
{
spiderman s;
captain_america c;

std::array<delegate<bool(int, int)>, 3> heros {
delegate(attack),
delegate(&s, &spiderman::attack),
delegate(&c, &captain_america::attack)
};

for (auto &h : heros) {
std::cout << h(0, 42) << ' ';
}

return 0;
}

When this is executed, we get the following output:

This delegate could further be extended to support lambda functions by adding yet another set of wrappers, and the need for std::unique_pointer in the delegate could be removed in favor of a placement new, using a small buffer the size of the member function wrapper (or, in other words, removing the dynamic memory allocation), which is sometimes referred to as a small size optimization.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset