$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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...