После довольно долгого времени отладки моего кода, я разыскал причину моих проблем в некоторые результатах неожиданного шаблона специализации с использованием enable_if:Странного поведения enable_if с помощью вложенных классов (? MSVC компилятора ошибки или функции)
Следующий код не утверждение в DoTest() в Visual Studio 2010 (и 2008), в то время как оно не в g ++ 3.4.5. Однако, когда я удаляю шаблон с SomeClass или переместим my_condition из области SomeClass он также работает в MSVC.
Есть ли что-то не так с этим кодом, что бы объяснить это поведение (по крайней мере частично) или это ошибка в компиляторе MSVC?
(используя этот пример кода, это то же самое для усиления и C++ 0x СТЛ версии)
#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;
}
При попытке исправить это, перемещая условие из сферы, я также заметил, что это не достаточно, даже при использовании зОго :: enable_if, но, по крайней мере, он работает с буст :: 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;
}
Я надеюсь, что кто-то объяснение этому.
Не удалось распечатать сообщение об ошибке из компилятора? Или это только утверждение неудачи? – doc
Из любопытства есть ли конкретная причина, по которой enable_if_tester должен быть структурой, а не методом? – Staffan
@ Стаффан: Частичная специализация. –