|
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