After quite some time debugging my code, I tracked down the reason for my problems to some unexpected template specialization results using enable_if:
The following code fails the assertion in DoTest() in Visual Studio 2010 (and 2008), while it doesn't in g++ 3.4.5. However, when i remove the template from SomeClass or move *my_condition* out of the scope of SomeClass it works in MSVC, too.
Is there something wrong with this code that would explain this behaviour (at least partially) or is this a bug in the MSVC compiler?
(using this example code it's the same for boost and the 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 it by moving the condition out of the scope, i also noticed that this isn't even enough 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;
}
I hope someone has an explanation for this.