[ 2009-08-02 Howard adds: ]
My current preferred solution is:
template <class T> struct __base_type { typedef typename remove_cv<typename remove_reference<T>::type>::type type; }; template <class T, class U, class = typename enable_if< !is_lvalue_reference<T>::value || is_lvalue_reference<T>::value && is_lvalue_reference<U>::value>::type, class = typename enable_if< is_same<typename __base_type<T>::type, typename __base_type<U>::type>::value>::type> inline T&& forward(U&& t) { return static_cast<T&&>(t); }This has been tested by Bill, Jason and myself.
It allows the following lvalue/rvalue casts:
- Cast an lvalue t to an lvalue T (identity).
- Cast an lvalue t to an rvalue T.
- Cast an rvalue t to an rvalue T (identity).
It disallows:
- Cast an rvalue t to an lvalue T.
- Cast one type t to another type T (such as int to double).
"a." is disallowed as it can easily lead to dangling references. "b." is disallowed as this function is meant to only change the lvalue/rvalue characteristic of an expression.
Jason has expressed concern that "b." is not dangerous and is useful in contexts where you want to "forward" a derived type as a base type. I find this use case neither dangerous, nor compelling. I.e. I could live with or without the "b." constraint. Without it, forward would look like:
template <class T, class U, class = typename enable_if< !is_lvalue_reference<T>::value || is_lvalue_reference<T>::value && is_lvalue_reference<U>::value>::type> inline T&& forward(U&& t) { return static_cast<T&&>(t); }Or possibly:
template <class T, class U, class = typename enable_if< !is_lvalue_reference<T>::value || is_lvalue_reference<T>::value && is_lvalue_reference<U>::value>::type, class = typename enable_if< is_base_of<typename __base_type<U>::type, typename __base_type<T>::type>::value>::type> inline T&& forward(U&& t) { return static_cast<T&&>(t); }The "promised paper" is not in the post-Frankfurt mailing only because I'm waiting for the non-concepts draft. But I'm hoping that by adding this information here I can keep people up to date.