
This is not a typo, I'm trying to emphasize that ref, cref, ... sequence lacks one element which imposes more strict requirements on its argument. According to IQ tests logic that sequence should be continued with ccref :) If seriously, cref allows silent binding of a temporary to a reference. Apparently, this is not always fine. Inspired by N1610 (thanks to Dave and Gary) I've tried to detect both const and non-const rvalues. I didn't yet opened my copy of the standard to check it but the code seems to work on g++ 3.2.2, g++ 3.4.0, Intel 8.0 (all under linux) and Comeau online. #include <boost/ref.hpp> template<class T1, class T2> struct enable_if_same { }; template<class T> struct enable_if_same<T,T> { typedef int type; }; template<class T> boost::reference_wrapper<T const> const ccref(T volatile& r, typename enable_if_same<T,T const>::type = 0) { return boost::reference_wrapper<T const>(const_cast<T const&>(r)); } struct convertible_to_int { operator int() const { return 0; } }; template<class T> boost::reference_wrapper<T const> const ccref(T const volatile& r) { return boost::reference_wrapper<T const>(const_cast<T const&>(r)); } int rvalue() { return 0; } int const const_rvalue() { return 0; } int main() { int i; int const j = 0; ccref(i); ccref(j); // Try uncommenting any of these lines: // ccref(rvalue()); // ccref(const_rvalue()); } -- Alexander Nasonov

I've just realised that this works as well: template<class T> boost::reference_wrapper<T const> const ccref(T const volatile& r) { return boost::reference_wrapper<T const>(const_cast<T const&>(r)); } It's late night now. I'll think about it tomorrow.

<alnsn@yandex.ru> writes:
This is not a typo, I'm trying to emphasize that ref, cref, ... sequence lacks one element which imposes more strict requirements on its argument. According to IQ tests logic that sequence should be continued with ccref :) If seriously, cref allows silent binding of a temporary to a reference. Apparently, this is not always fine.
Maybe you should show an example of code where the use of ref/cref causes a problem. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
Maybe you should show an example of code where the use of ref/cref causes a problem.
using namespace std; using namespace boost; template<class T> reference_wrapper<T const> head(vector<T> const& v) { return cref(v[0]); // binds with temporary if T == bool } int main() { bool buf[1] = {}; vector<bool> v(buf, buf + 1); reference_wrapper<bool const> r = head(v); } Similar problem with ref: int const const_rvalue(); ref(const_rvalue()); // binds with a temporary Is it possible to protect from this effect at least for ref case? -- Alexander Nasonov

alnsn@yandex.ru wrote:
David Abrahams wrote:
Maybe you should show an example of code where the use of ref/cref causes a problem.
using namespace std; using namespace boost;
template<class T> reference_wrapper<T const> head(vector<T> const& v) { return cref(v[0]); // binds with temporary if T == bool }
return ref( v[0] ); // ?
participants (3)
-
alnsn@yandex.ru
-
David Abrahams
-
Peter Dimov