|
Boost : |
Subject: [boost] [move] forward with lvalue ref template param
From: Andrew Ho (helloworld922_at_[hidden])
Date: 2013-08-08 18:26:14
Hi during my implementation of unique_ptr I noticed that boost::forward
doesn't play nicely with lvalue ref types.
int a;
int &b = a;
int &c = std::forward<int&>(b); // compiles fine
int &d = boost::forward<int&>(b); // compiler error
I did a little playing around with the declarations of forward and I managed
to get this to work:
// if T is not a lvalue ref and movable
template <class T>
inline typename ::boost::move_detail::enable_if_c
< enable_move_utility_emulation<T>::value &&
::boost::move_detail::is_rv<T>::value &&
!::boost::move_detail::is_lvalue_reference<T>::value, const T &>::type
forward(typename ::boost::move_detail::identity<T>::type &x)
BOOST_NOEXCEPT
{
return const_cast<T&>(x);
}
// if T is not a lvalue ref and not movable
template <class T>
inline typename ::boost::move_detail::enable_if_c
< enable_move_utility_emulation<T>::value &&
!::boost::move_detail::is_rv<T>::value &&
!::boost::move_detail::is_lvalue_reference<T>::value, const T
&>::type
forward(const typename ::boost::move_detail::identity<T>::type &x)
BOOST_NOEXCEPT
{
return x;
}
// if T is a lvalue ref
template <class T>
inline typename ::boost::move_detail::enable_if_c
< ::boost::move_detail::is_lvalue_reference<T>::value , T>::type
forward(T x) BOOST_NOEXCEPT
{
return x;
}
Basically, this forces all calls to forward<A&> to simply return the lvalue
ref (const-ness is maintained, I think), otherwise it does whatever
boost::forward did before.
As far as I can tell, this doesn't break boost::forward, and it enables it
to properly handle taking lvalue refs. Am I right in my assumptions? Are
there any cases where this would fail to produce standard-compliant/desired
results?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk