Comportement enable_if étrange à l'aide de classes imbriquées (insecte ou fonctionnalité de compilateur MSVC?)
-
13-09-2020 - |
Question
Après un certain temps de débogage de mon code, j'ai suivi la raison de mes problèmes à des résultats de spécialisation de modèles inattendus à l'aide d'activation_if:
Le code suivant échoue à l'affirmation dans Dotest () dans Visual Studio 2010 (et 2008), alors qu'elle ne le fait pas dans G ++ 3.4.5. Cependant, lorsque je retire le modèle de soméclass ou déplacez my_condition hors de la portée de Someclass Il fonctionne également dans MSVC.
Y a-t-il un problème avec ce code qui expliquerait ce comportement (au moins partiellement) ou est-ce qu'un bogue dans le compilateur MSVC?
(en utilisant cet exemple de code, il est identique à Boost et à la version STL 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;
}
Lorsque vous essayez de le réparer en déplaçant la condition hors de la portée, j'ai également remarqué que cela ne suffit même pas lorsque vous utilisez STD :: Enable_if, mais au moins cela fonctionne avec boost ::able_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 à cela.
La solution
Tout va bien avec votre code, c'est juste que VC est buggy.Il est connu d'avoir des problèmes de spécialisation partielle de modèles de classes de membres de modèle.