How to do it...

The std::invoke() function is a variadic function template that takes the callable object as the first argument and a variable list of arguments that are passed to the call. std::invoke() can be used to call the following:

  • Free functions:
        auto a1 = std::invoke(add, 1, 2);   // a1 = 3
  • Free functions through pointer to function:
        auto a2 = std::invoke(&add, 1, 2);  // a2 = 3 
int(*fadd)(int const, int const) = &add;
auto a3 = std::invoke(fadd, 1, 2); // a3 = 3
  • Member functions through pointer to member function:
        foo f; 
std::invoke(&foo::increment_by, f, 10);
  • Data members:
        foo f; 
auto x1 = std::invoke(&foo::x, f); // x1 = 0

  • Function objects:
        foo f; 
auto x3 = std::invoke(std::plus<>(),
std::invoke(&foo::x, f), 3); // x3 = 3
  • Lambda expressions:
        auto l = [](auto a, auto b) {return a + b; }; 
auto a = std::invoke(l, 1, 2); // a = 3

In practice, std:invoke() should be used in template meta-programming for invoking a function with an arbitrary number of arguments. To exemplify such a case, we present a possible implementation for our std::apply() function, and also a part of the standard library as of C++17 that calls a function by unpacking the members of a tuple into the arguments of the function:

    namespace details 
{
template <class F, class T, std::size_t... I>
auto apply(F&& f, T&& t, std::index_sequence<I...>)
{
return std::invoke(
std::forward<F>(f),
std::get<I>(std::forward<T>(t))...);
}
}

template <class F, class T>
auto apply(F&& f, T&& t)
{
return details::apply(
std::forward<F>(f),
std::forward<T>(t),
std::make_index_sequence<
std::tuple_size<std::decay_t<T>>::value> {});
}

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

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