
Hi, While working on some portability for Boost.Test I found this weird behavior. Abstracting out Boost.Test specific staff it goes like this: template<typename T> inline typename boost::enable_if_c<!boost::is_float<T>::value, int>::type foo( T&& v ); template<typename T> inline typename boost::enable_if_c<!boost::is_float<T>::value, int>::type foo( T&& v ) { return 1; } ... foo(1); MSVC 10 producing this error: error C2668: 'foo' : ambiguous call to overloaded function test.cpp(31): could be 'int foo<int>(T &&)' with [ T=int ] test.cpp(27): or 'int foo<int>(T &&)' with [ T=int ] while trying to match the argument list '(int)' Now change boost::enable_if_c with seemingly equivalent std::enable_if: template<typename T> inline typename std::enable_if<!boost::is_float<T>::value, int>::type foo( T&& v ); template<typename T> inline typename std::enable_if<!boost::is_float<T>::value, int>::type foo( T&& v ) { return 1; } and MSVC 10 is happy to accept this code. This is somewhat unfortunate since I hoped to use boost::enable_if across compilers. Gennadiy

11.11.2012 11:20, Gennadiy Rozental wrote:
template<typename T> inline typename boost::enable_if_c<!boost::is_float<T>::value, int>::type foo( T&& v );
template<typename T> inline typename boost::enable_if_c<!boost::is_float<T>::value, int>::type foo( T&& v ) { return 1; }
... foo(1);
MSVC 10 producing this error:
I have just reproduced this error on MSVC2010. BTW, disable_if_c seems like works: template<typename T> inline typename boost::disable_if_c<boost::is_float<T>::value, int>::type foo( T&& v ); template<typename T> inline typename boost::disable_if_c<boost::is_float<T>::value, int>::type foo( T&& v ) { return 1; } -- Evgeny Panasyuk

On Sun, Nov 11, 2012 at 12:29 AM, Evgeny Panasyuk <evgeny.panasyuk@gmail.com
wrote:
11.11.2012 11:20, Gennadiy Rozental wrote:
template<typename T>
inline typename boost::enable_if_c<!boost::is_**float<T>::value, int>::type foo( T&& v );
template<typename T> inline typename boost::enable_if_c<!boost::is_**float<T>::value, int>::type foo( T&& v ) { return 1; }
... foo(1);
MSVC 10 producing this error:
I have just reproduced this error on MSVC2010. BTW, disable_if_c seems like works:
template<typename T> inline typename boost::disable_if_c<boost::is_**float<T>::value, int>::type foo( T&& v );
template<typename T> inline typename boost::disable_if_c<boost::is_**float<T>::value, int>::type foo( T&& v ) { return 1; }
This is disturbing. I don't have MSVC2010, so I can't investigate, but maybe it's the use of "!"? I know MSVC has traditionally been quirky with integral constant expressions in template parameters. Gennadiy or Evgeny, does boost::enable_if_c< boost::mpl::not_< boost::is_float<T> >::value, int
::type
work? That, or I think there's an ice_not buried in Boost.TypeTraits somewhere. - Jeff

11.11.2012 22:33, Jeffrey Lee Hellrung, Jr. wrote:
This is disturbing. I don't have MSVC2010, so I can't investigate, but maybe it's the use of "!"? I know MSVC has traditionally been quirky with integral constant expressions in template parameters. Gennadiy or Evgeny, does
boost::enable_if_c< boost::mpl::not_< boost::is_float<T> >::value, int
::type
work? That, or I think there's an ice_not buried in Boost.TypeTraits somewhere.
I have just checked, following code works OK: template<typename T> inline typename boost::enable_if_c<boost::mpl::not_< boost::is_float<T>
::value, int>::type foo( T&& v );
template<typename T> inline typename boost::enable_if_c<boost::mpl::not_< boost::is_float<T>
::value, int>::type foo( T&& v ) { return 1; }
-- Evgeny Panasyuk

On Sun, Nov 11, 2012 at 2:20 AM, Gennadiy Rozental <rogeeff@gmail.com>wrote:
template<typename T> inline typename boost::enable_if_c<!boost::is_float<T>::value, int>::type foo( T&& v ) { return 1; }
... foo(1);
MSVC 10 producing this error:
Uggg. That's definitely a compiler bug, and a very annoying one at that. As was suggested, using the type form of enable_if should probably work. On the plus side, I imagine this bug will be fixed given that there is std::enable_if now, which takes a boolean constant (and no corresponding disable_if or type forms), so people even outside of the boost community will be running into the same problem. -- -Matt Calabrese

On Sun, Nov 11, 2012 at 1:41 PM, Matt Calabrese <rivorus@gmail.com> wrote:
Uggg. That's definitely a compiler bug, and a very annoying one at that. As was suggested, using the type form of enable_if should probably work. On the plus side, I imagine this bug will be fixed given that there is std::enable_if now, which takes a boolean constant (and no corresponding disable_if or type forms), so people even outside of the boost community will be running into the same problem.
Oh whoa, I somehow missed that the std:: version works... That's... odd... -- -Matt Calabrese
participants (4)
-
Evgeny Panasyuk
-
Gennadiy Rozental
-
Jeffrey Lee Hellrung, Jr.
-
Matt Calabrese