enable_if question

Folks I'm having some difficulties understanding the subtleties of enable_if, consider: using namespace boost; template <unsigned B> struct dummy {}; template <unsigned B, class Integer> typename boost::enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<(sizeof(Integer) <= sizeof(long))> > >::type bar(dummy<B>&, const Integer&) { } template <unsigned B, class Integer> typename boost::enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<(sizeof(Integer) <= sizeof(long))> > >::type bar(dummy<B>&, const Integer&) { } Then calling: dummy<2> d; bar(d, 2); Leads to an ambiguity between the two overloads (both gcc and VC++10), how can that be? However, changing the condition to: template <unsigned B, class Integer> typename boost::enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<(B || !B) && (sizeof(Integer) <= sizeof(long))> > >::type bar(dummy<B>&, const Integer&) { } template <unsigned B, class Integer> typename boost::enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<(B || !B) && (sizeof(Integer) <= sizeof(long))> > >::type bar(dummy<B>&, const Integer&) { } "fixes" things. But this fix isn't always possible. Thoughts? Thanks, John.

On Tue, 8 May 2012, John Maddock wrote:
Folks I'm having some difficulties understanding the subtleties of enable_if, consider:
using namespace boost;
template <unsigned B> struct dummy {};
template <unsigned B, class Integer> typename boost::enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<(sizeof(Integer) <= sizeof(long))> > >::type bar(dummy<B>&, const Integer&) { } template <unsigned B, class Integer> typename boost::enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<(sizeof(Integer) <= sizeof(long))> > >::type bar(dummy<B>&, const Integer&) { }
Then calling:
dummy<2> d; bar(d, 2);
Leads to an ambiguity between the two overloads (both gcc and VC++10), how can that be?
The code works for me (as written above) on GCC 4.7 (both with -m32 and -m64 on x86-64, and with -std=c++98 and -std=c++0x, -ansi -pedantic). I don't see a reason that it would be ambiguous. -- Jeremiah Willcock

The code works for me (as written above) on GCC 4.7 (both with -m32 and -m64 on x86-64, and with -std=c++98 and -std=c++0x, -ansi -pedantic). I don't see a reason that it would be ambiguous.
My bad, you're quite right. The problem I can only reproduce with VC10 and when a certain header is #included before the code in question - in fact it's a particular usage of enable_if in that header that triggers the problem - I can't boil it down to a reduced test case though, so it's going to be one of those strange compiler quirks I guess. Very annoying though :-( Thanks, John.
participants (2)
-
Jeremiah Willcock
-
John Maddock