
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...