
Eric Niebler: ...
Now take a look at what happens when I do this:
BigObject const obj; compose< identity, make_tuple >()( obj );
(And assume that make_tuple is implemented as you implemented it above.) Now it looks to me like the wrong thing is going to happen here. In the return type calculation, make_tuple is being told it is going to get an lvalue (BigObject const &). But the rvalue overload of make_tuple::operator() is going to be selected, causing BigObject to be copied when it shouldn't be -- if it even compiles at all.
Doesn't make_tuple()(obj) have the exact same problem? compose<identity,make_tuple> faithfully reproduces it.
So where have I screwed up my logic?
Nowhere. But I don't think that this problem is somehow caused by result_of. If you replace every result_of occurence with <magic happens here> the result would be the same. Can you give an example in which compose<identity,make_tuple>, implemented within your new framework, is able to avoid the problem?