Opened 12 years ago

Closed 12 years ago

#4530 closed Bugs (fixed)

errors with is_convertible on msvc10

Reported by: Christopher Schmidt Owned by: John Maddock
Milestone: Boost 1.44.0 Component: type_traits
Version: Boost Development Trunk Severity: Problem
Keywords: Cc:

Description

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

template<typename T>
struct test
{
	template<typename A>
	test(A&&, typename boost::enable_if<boost::is_convertible<A&&, T> >::type* =0);
};

int main()
{
	typedef boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard,true,false> A;

	boost::is_convertible<test<A>, A>::value;
	//std::tr1::is_convertible<test<A>, A>::value;
}

This snippet fails on msvc10 with the following errors:

1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2039: 'value' : is not a member of 'boost::detail::is_convertible_basic_impl<From,To>'
1>          with
1>          [
1>              From=test<A> ,
1>              To=A
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(372) : see reference to class template instantiation 'boost::detail::is_convertible_impl<From,To>' being compiled
1>          with
1>          [
1>              From=test<A> ,
1>              To=A
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(418) : see reference to class template instantiation 'boost::detail::is_convertible_impl_dispatch<From,To>' being compiled
1>          with
1>          [
1>              From=test<A> ,
1>              To=A
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\utility\enable_if.hpp(36) : see reference to class template instantiation 'boost::is_convertible<From,To>' being compiled
1>          with
1>          [
1>              From=test<A> &,
1>              To=A
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(263) : see reference to class template instantiation 'boost::enable_if<Cond,T>' being compiled
1>          with
1>          [
1>              Cond=boost::is_convertible<test<A> &,A>,
1>              T=void
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295) : see reference to class template instantiation 'boost::detail::is_convertible_basic_impl<From,To>' being compiled
1>          with
1>          [
1>              From=test<A> ,
1>              To=A
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(372) : see reference to class template instantiation 'boost::detail::is_convertible_impl<From,To>' being compiled
1>          with
1>          [
1>              From=test<A>,
1>              To=A
1>          ]
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(418) : see reference to class template instantiation 'boost::detail::is_convertible_impl_dispatch<From,To>' being compiled
1>          with
1>          [
1>              From=test<A>,
1>              To=A
1>          ]
1>          z:\dev\projekte\_test\main.cpp(17) : see reference to class template instantiation 'boost::is_convertible<From,To>' being compiled
1>          with
1>          [
1>              From=test<A>,
1>              To=A
1>          ]
1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2065: 'value' : undeclared identifier
1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2955: 'boost::type_traits::ice_or' : use of class template requires template argument list
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\detail\ice_or.hpp(21) : see declaration of 'boost::type_traits::ice_or'
1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(295): error C2057: expected constant expression
1>z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\is_convertible.hpp(418): error C2975: 'val' : invalid template argument for 'boost::integral_constant', expected compile-time constant expression
1>          z:\dev\projekte\boost\boost-dev\boost\boost\type_traits\integral_constant.hpp(18) : see declaration of 'val'

Switching to std::tr1::is_convertible makes the code compile fine.

Change History (2)

comment:1 by John Maddock, 12 years ago

Status: newassigned

Hmmm... I think this is a compiler bug, in trying to work out if test<A> is convertible to A the compiler is for some reason trying to instantiate test<A>::test<A>(test<A>) which causes a cyclic dependency in is_convertible. GCC handles the same code just fine, and switching to std::tr1::is_convertible at the top level breaks the cyclic dependency.

I think I can fix this long term by switching over to using the _ _is_convertible compiler intrinsic - but this also means switching is_convertible over to C++0x behaviour from TR1 behaviour which will be a breaking change.... and I'm not sure C++0x behaviour can even be implemented in the language yet for compilers that don't have the intrinsic!

Will investigate some more.

comment:2 by John Maddock, 12 years ago

Resolution: fixed
Status: assignedclosed

(In [69822]) Change is_convertible to use C++0x behaviour where possible. Change is_converible to use MSVC is_convertible intrinsic. Fixes #5271. Fixes #4530.

Note: See TracTickets for help on using tickets.