2017-06-03 3 views
0

Récemment tout en répondant à une question ici if-else depends on whether T is a complete type je compris que ce qui suit ne compile pasRègles particulières concernant SFINAE pour les types incomplets

#include <iostream> 
#include <type_traits> 

using namespace std; 

class Incomplete; 
class Complete {}; 

template <typename IncompleteType> 
struct DetermineCompleteHelper : public IncompleteType {}; 

template <typename IncompleteType, typename = std::enable_if_t<true>> 
struct DetermineComplete { 
    static constexpr const bool value = false; 
}; 

template <typename IncompleteType> 
struct DetermineComplete<IncompleteType, std::enable_if_t<std::is_same< 
     decltype(DetermineCompleteHelper<IncompleteType>{}), 
     decltype(DetermineCompleteHelper<IncompleteType>{})>::value>> { 
    static constexpr const bool value = true; 
}; 

int main() { 
    cout << DetermineComplete<Complete>::value << endl; 
    cout << DetermineComplete<Incomplete>::value << endl; 
    return 0; 
} 

Mais changer la spécialisation de modèle partielle

template <typename IncompleteType> 
struct DetermineComplete<IncompleteType, std::enable_if_t<std::is_same< 
     std::integer_sequence<int, sizeof(IncompleteType)>, 
     std::integer_sequence<int, sizeof(IncompleteType)>>::value>> { 
    static constexpr const bool value = true; 
}; 

fait la compilation de code sans erreurs, pourquoi cette irrégularité? Est-ce que la première expression ne devrait pas être traitée comme une erreur dans le contexte de la spécialisation partielle et donc avoir SFINAE kick et faire de la définition par défaut de la classe celle qui est instanciée?

Répondre

3

L'erreur se produit lors de la tentative d'instanciation de la définition de DetermineCompleteHelper<IncompleteType> (en particulier, elle tente de dériver à partir d'une classe de base incomplète). C'est en dehors du contexte immédiat.

+0

Comment 'sizeof (DetemineCompleteHelper )' est-il dans le contexte immédiat? Cela n'essaiera-t-il pas aussi de voir quelle est la taille de la classe une fois instanciée? – Curious

+0

@Curious Votre exemple de "compilation" est 'sizeof (IncompleteType)'. –

+0

... nvm, j'ai demandé trop tôt il semble que, aurait dû lire le code que j'ai écrit avant de demander – Curious