Après un certain temps de débogage mon code, je traqué la raison de mes problèmes à certains résultats de spécialisation de modèle inattendu en utilisant enable_if:Comportement étrange de enable_if en utilisant des classes imbriquées (? MSVC bug du compilateur ou fonctionnalité)
Le code suivant échoue l'assertion dans DoTest() dans Visual Studio 2010 (et 2008), alors que ce n'est pas le cas dans g ++ 3.4.5. Cependant, lorsque je supprime le modèle de SomeClass ou de déplacer my_condition hors de la portée de SomeClass il fonctionne aussi en MSVC.
Y at-il un problème avec ce code qui expliquerait ce comportement (au moins partiellement) ou s'agit-il d'un bogue dans le compilateur MSVC?
(en utilisant ce code exemple, il est le même pour stimuler et C++ 0x version stl)
#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;
}
Lorsque vous essayez de le corriger en déplaçant la condition hors de la portée, j'ai aussi remarqué que cela ne suffit pas même lorsque vous utilisez std :: enable_if, mais au moins il fonctionne avec 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;
}
J'espère que quelqu'un a une explication pour cela.
Pourriez-vous imprimer un message d'erreur du compilateur? Ou est-ce seulement l'échec d'assertion? – doc
Par curiosité, y a-t-il une raison particulière à ce que enable_if_tester soit une structure plutôt qu'une méthode? – Staffan
@Staffan: Spécialisation partielle. –