Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2006-09-06 03:19:01


Tim Robertson <timr_at_[hidden]> writes:

> Hi,
>
> Can anyone explain why the following won't compile (using g++ 3.3.2
> under Linux):
>
> #include <boost/utility/enable_if.hpp>
> #include <boost/type_traits/is_convertible.hpp>
>
> using namespace std;
>
> struct Foo
> {
> Foo() {}
>
> template <typename T>
> Foo(T const & src,
> typename boost::enable_if<
> boost::is_convertible<T,Foo>, void >::type * dummy = 0)
> {
> int i = 1; // filler.
> }
>
> template <typename T>
> Foo(T const & src,
> typename boost::disable_if<
> boost::is_convertible<T,Foo>, void >::type * dummy = 0)
> {
> int i = 2; // ditto.
> }
>
> };
>
> int main()
> {
> Foo f;
> Foo f2(f);
>
> return 0;
> };
>
>
> When I attempt to compile this code with g++ 3.3.2, I get the following
> error messages:

Well, first of all, neither of those two constructors is a copy ctor
(a copy ctor has the signature Foo(Foo <cv>&) -- no templates), so the
compiler should be instantiating the implicitly-generated copy ctor,
and, I think, accept your code without complaint.

But that's probably not what you meant for it to do. In this case
it looks like you have a kind of circular dependency problem. You can
actually learn a lot by reading the error messages. Reversing your
instantiation backtrace, I get:

> test.cpp:36: instantiated from here

I assume that's the 2nd line of main()

> test.cpp:36: instantiated from `boost::enable_if<boost::is_convertible<Foo, Foo>, void>'

It's trying to decide if the first ctor is a match

> test.cpp:36: instantiated from `boost::is_convertible<Foo, Foo>'

To do that it needs to decide the value nested in is_convertible<Foo,Foo>.

> test.cpp:36: instantiated from `boost::detail::is_convertible_impl_dispatch<Foo, Foo>'
> /boost/boost/type_traits/is_convertible.hpp:228: instantiated from `boost::detail::is_convertible_impl<Foo, Foo>'
> /boost/boost/type_traits/is_convertible.hpp:128: instantiated from `boost::detail::is_convertible_basic_impl<Foo&, Foo>'

Inside implementation details of is_convertible:

> /boost/boost/type_traits/is_convertible.hpp: In instantiation of `boost::disable_if<boost::is_convertible<Foo, Foo>, void>':

To determine convertibility it has to check out the ctors and see if
there's one that implicitly converts Foo->Foo

> /boost/boost/type_traits/is_convertible.hpp:128: error: `value' is not a member of type `boost::is_convertible<Foo, Foo>'

In evaluating the applicability of the first ctor, it needs to know
the value nested in is_convertible<Foo,Foo>. We've been here before!

HTH,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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