They are both used as a generic method of calling functions, member functions and generally anything that is callable. From cppreference the only real difference I see is that in
std::invoke the function parameters (however many they are) are
forwarded to the function, whereas in
std::apply the parameters are passed as a
tuple. Is this really the only difference? Why would they create a separate function just to handle
Is this really the only difference? Why would they create a separate function just to handle tuples?
Because you really need both options, since they do different things. Consider:
int f(int, int); int g(tuple<int, int>); tuple<int, int> tup(1, 2); invoke(f, 1, 2); // calls f(1, 2) invoke(g, tup); // calls g(tup) apply(f, tup); // also calls f(1, 2)
Consider especially the difference between
invoke(g, tup), which does not unpack the
apply(f, tup), which does. You sometimes need both, that needs to be expressed somehow.
You're right that generally these are very closely related operations. Indeed, Matt Calabrese is writing a library named Argot that combines both operations and you differentiate them not by the function you call but rather by how you decorate the arguments:
call(f, 1, 2); // f(1,2) call(g, tup); // g(tup) call(f, unpack(tup)); // f(1, 2), similar to python's f(*tup)