Boost logo

Boost Users :

From: Tim Robertson (timr_at_[hidden])
Date: 2006-09-06 16:47:00


I worked up a much better example of what I'm trying to do:

///////////////////////////////////////////////////////////////////////
//////////////////////////////

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>

using namespace std;

template <typename T>
struct MyValueType
{
   typedef MyValueType<T> self_type;

   MyValueType() {}
   MyValueType(self_type const & v) {}

   template <typename V>
   MyValueType(V const & v,
              typename boost::enable_if<
              boost::is_convertible<V,self_type> >::type * dummy = 0)
   {
     cout << "MyValueType template constructor 1" << endl;
   }

   template <typename V>
   MyValueType(V const & v,
              typename boost::disable_if<
              boost::is_convertible<V,self_type> >::type * dummy = 0)
   {
     cout << "MyValueType template constructor 2" << endl;
   }
};

template <typename T>
struct MyContainer
{
   typedef T value_type;
   typedef MyContainer<T> self_type;

   MyContainer() {}
   MyContainer(MyContainer const & c) {}

   template <typename C>
   MyContainer(C const & c,
              typename boost::enable_if<
                boost::is_convertible<typename C::value_type,
                                      value_type>
>::type * dummy = 0)
   {
     cout << "MyContainer template constructor 1" << endl;
   }
        
   template <typename C>
   MyContainer(C const & c,
              typename boost::disable_if<
                boost::is_convertible<typename C::value_type,
                                      value_type>
>::type * dummy = 0)
   {
     cout << "MyContainer template constructor 2" << endl;
   }
};

typedef MyValueType<int> integer_value;
typedef MyValueType<double> real_value;

typedef MyContainer<integer_value> integer_container;
typedef MyContainer<real_value> real_container;

int main()
{
   integer_container ic;

   real_container rc(ic);

   return 0;
};

///////////////////////////////////////////////////////////////////////
//////////////////////////////

In this case, compiling with the first set of typedefs results in the
following errors:

/boost/boost/utility/enable_if.hpp: In instantiation of
'boost::disable_if<boost::is_convertible<integer_value,
MyValueType<double> >, void>':

boost/boost/type_traits/is_convertible.hpp:128: instantiated from
'boost::detail::is_convertible_basic_impl<integer_value&,
MyValueType<double> >'

/boost/boost/type_traits/is_convertible.hpp:228: instantiated from
'boost::detail::is_convertible_impl<integer_value, MyValueType<double>
>'

/boost/boost/type_traits/is_convertible.hpp:302: instantiated from
'boost::detail::is_convertible_impl_dispatch<integer_value,
MyValueType<double> >'

/boost/boost/type_traits/is_convertible.hpp:348: instantiated from
'boost::is_convertible<integer_value, MyValueType<double> >'

/boost/boost/utility/enable_if.hpp:36: instantiated from
'boost::enable_if<boost::is_convertible<integer_value,
MyValueType<double> >, void>'

test.cpp:72: instantiated from here (**This is the call to the copy
constructor in main()**)

/boost/boost/utility/enable_if.hpp:59: error: incomplete type
'boost::is_convertible<integer_value, MyValueType<double> >' used in
nested name specifier

 From what I can tell, this looks like the same problem that I was
having in the much simpler example -- the compiler wants to instantiate
is_convertible<integer_value,real_value>, and in order to do this, it
needs the constructors in MyValueType, which are themselves
enabled/disabled with enable_if<> and disable_if<>.

Is there a way that I can make this work without having to resort to
using is_same<> (which works, but doesn't capture the sematics that I
need)?

Thanks again,
Tim

On Sep 6, 2006, at 1:13 PM, Tim Robertson wrote:
> In retrospect, this was probably too trivial an example to give you --
> I realize that it's silly to want to use enable_if<> to do what the
> compiler can do for itself. There's a far more complex situation
> behind the question, but I'm having trouble distilling it down to a
> question of reasonable length...


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net