On 16 Mrz., 09:33, SG wrote:
> [...] To get what you want we
> would need some kind of constrained template and new overload
> resolution rules based on these constraints. Example:
>
> * template<class T>
> * requires T=U* or T=U*& for some type U
> * void fwd(T&&);
Or an alternative way to do perfect forwarding. You *did* point out
with your example that deduction w.r.t. "special, more restrictive
patters" a la T* is not orthogonal to the feature that allows us to
detect lvalues and rvalues. So, for a proper "orthogonal" approach we
could introduce a new kind of template parameter:
template<class T, qualifier Q>
void fwd(T* Q x);
where Q can be one of the 12=2*2*3 combinations you get by pairing
const/nonconst, volatile/nonvolatile and [no reference]/&/&&. The
deduction rule for Q would pick an lvalue reference for lvalues and an
rvalue reference for rvalues.
This way, we get rid of the issue you pointed out (w.r.t.
orthogonality), we can get rid of the funny/special deduction rule for
T&& (which is already known to cause trouble (*)) and also get a nice
way of expressing member function types
template<class R, class C, qualifier Q, class... P>
void (R (C::*memfunptr)(P...) Q);
without the need to overload std::bind for 12 different combinations
of qualifiers.
On the other hand, getting rid of the funny/special deduction rule for
the "T&&" pattern would force us to use two template parameters to do
perfect forwarding for just one function argument:
template<class...P, qualifiers...Q>
void outer(P Q... params)
{
inner(std::forward<P Q>(params)...);
}
I'm not sure about other implications, but it seems to be worth
thinking about it.
Cheers!
SG
