My actual usecase takes a few more arguments but it simplifies to this:
template< typename Arg1 >
bool algorithm( Arg1&& p1, **p2 here** );
With just that its evident that Arg1 will collapse in some way and likely become some kind of reference. p1 is also an output of the algorithm and so if the caller chooses to pass in an lvalue, the function will return with the original parameter modified to reflect where it left off.
However p2 is of the same type but will never be modified. So actually I'd like to put a 'const' promise in there for correctness. Clearly if Arg1 deduces to be a reference, I cannot add const to it.
So my solution is this:
template< class T >
struct make_const_ref
{
typedef typename std::add_reference< typename std::add_const< typename std::remove_reference< T >::type >::type >::type type;
};
template< typename Arg1 >
bool algorithm( Arg1&& p1, typename make_const_ref<Arg1>::type p2 );
Which goes through a bunch of silly machinations to remove some qualifiers and then stick the const& back on.
So my questions are:
1) Is this the best way of doing it?
2) Is there a context under which this will fail? Right now it seems pretty good to me.