Being Generic in Templates
So far, we have learned how the compiler can make our templated functions easier to use by automatically deducing the types used. The template code decides whether to accept a parameter as a value or a reference, and the compiler finds the type for us. But what do we do if we want to be agnostic regarding whether an argument is a value or a reference, and we want to work with it regardless?
An example would be std::invoke in C++17. std::invoke is a function that takes a function as the first argument, followed by a list of arguments, and calls the function with the arguments. For example:
void do_action(int, float, double); double d = 1.5; std::invoke(do_action, 1, 1.2f, d);
Similar examples would apply if you wanted to log before calling a function, or you wanted to execute the function in a different thread, such as std::async does.
Let's demystify the difference by using the following code:
struct PrintOnCopyOrMove { PrintOnCopyOrMove(std::string name) : _name...