Boost logo

Boost :

Subject: [boost] is_convertible problems associated with move-only types
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2009-01-05 18:17:15


I'm continuing to refine a boost::unique_ptr emulation and testsuite.
One thing I've just uncovered is that I'm hitting a brick wall with
is_convertible and move-only deleters used within the unique_ptr move
constructor. The problem is that boost::is_convertible<From, To>
assumes From is an lvalue. is_convertible<Deleter, Deleter> gets
instantiated and it is all over.

I've modified my copy of is_convertible (without really knowing what
I'm doing) like so:

Index: is_convertible.hpp
===================================================================
--- is_convertible.hpp (revision 50433)
+++ is_convertible.hpp (working copy)
@@ -119,6 +119,8 @@
  struct any_conversion
  {
      template <typename T> any_conversion(const volatile T&);
+ template <typename T> any_conversion(volatile T&);
+ template <typename T> any_conversion(const T&);
      template <typename T> any_conversion(T&);
  };

@@ -131,8 +133,8 @@
  template <typename From, typename To>
  struct is_convertible_basic_impl
  {
- static From _m_from;
- static bool const value =
sizeof( detail::checker<To>::_m_check(_m_from, 0) )
+ static From _m_from();
+ static bool const value =
sizeof( detail::checker<To>::_m_check(_m_from(), 0) )
          == sizeof(::boost::type_traits::yes_type);
  };

@@ -291,7 +293,8 @@
  template <typename From, typename To>
  struct is_convertible_impl
  {
- typedef typename add_reference<From>::type ref_type;
+// typedef typename add_reference<From>::type ref_type;
+ typedef From ref_type;
      BOOST_STATIC_CONSTANT(bool, value =
          (::boost::type_traits::ice_and<
              ::boost::type_traits::ice_or<

This hits just the part targeting gcc.

The intent is that in boost::is_convertible<From, To> From is now
considered an rvalue (unless From is a (lvalue) reference type). This
makes my test case happy. I can now move construct a unique_ptr with
a move-only deleter.

Fwiw, this definition of is_convertible is consistent with
std::is_convertible in N2800:

> In order to instantiate the template is_convertible<From, To>, the
> following code shall be well formed:
>
> template <class T>
> typename add_rvalue_reference<T>::type create();
> To test() {
> return create<From>();
> }
>
> [ Note: This requirement gives well defined results for reference
> types,
> void types, array types, and function types. -- end note ]

I've got a much more refined unique_ptr testsuite on the way which
will contain the unique_ptr header and test case for this (not there
yet, I'll post when it is).

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk