After debugging my code for quite some time, I tracked down the cause of my problems with some unexpected results of template specialization using enable_if:
The following code does not execute the statement in DoTest () in Visual Studio 2010 (and 2008), while it is not in g ++ 3.4.5. However, when I delete a template from SomeClass or move my_condition from SomeClass, it also works in MSVC.
Is there something wrong with this code that would explain this behavior (at least in part) or is it an error in the MSVC compiler?
(using this sample code, it is the same for boost and C ++ 0x stl version)
#include <cassert> #include <boost\utility\enable_if.hpp> template <class X> class SomeClass { public: template <class T> struct my_condition { static const bool value = true; }; template <class T, class Enable = void> struct enable_if_tester { bool operator()() { return false; } }; template <class T> struct enable_if_tester<T, typename boost::enable_if< my_condition<T> >::type> { bool operator()() { return true; } }; template <class T> void DoTest() { enable_if_tester<T> test; assert( test() ); } }; int main() { SomeClass<float>().DoTest<int>(); return 0; }
When trying to fix this by moving the condition out of scope, I also noticed that this is not enough even when using std :: enable_if, but at least it works with boost :: enable_if:
#include <cassert> //#include <boost\utility\enable_if.hpp> #include <type_traits> template <class T, class X> struct my_condition { static const bool value = true; }; template <class X> class SomeClass { public: template <class T, class Enable = void> struct enable_if_tester { bool operator()() { return false; } }; template <class T> //struct enable_if_tester<T, typename boost::enable_if< my_condition<T, X> >::type> { struct enable_if_tester<T, typename std::enable_if< my_condition<T, X>::value >::type> { bool operator()() { return true; } }; template <class T> void DoTest() { enable_if_tester<T> test; assert( test() ); } }; int main() { SomeClass<float>().DoTest<int>(); return 0; }
Hope someone has an explanation.
source share