In perfect forwarding, std::forward is used to convert the named rvalue references t1 and t2 to unnamed rvalue references. What is the
How would that affect the called function inner if we leave t1 & t2 as lvalue?
If, after instantiating, T1 is of type char, and T2 is of a class, you want to pass t1 per copy and t2 per const reference. Well, unless inner() takes them per non-const reference, that is, in which case you want to do so, too.
Try to write a set of outer() functions which implement this without rvalue references, deducing the right way to pass the arguments from inner()'s type. I think you'll need something 2^2 of them, pretty hefty template-meta stuff to deduce the arguments, and a lot of time to get this right for all cases.
And then someone comes along with an inner() that takes arguments per pointer. I think that now makes 3^2. (Or 4^2. Hell, I can't be bothered to try to think whether const pointer would make a difference.)
And then imagine you want to do this for a five parameters. Or seven.
Now you know why some bright minds came up with "perfect forwarding": It makes the compiler do all this for you.