2016-12-15 2 views
1

J'ai deux ensembles de code, dont le premier Compile et se comporte comme prévu, mais est [semblant être] inutilement bavard:Métaprogrammation de modèles avec caractères de type: Pourquoi le premier code compile-t-il et le second pas?

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    template<point_type t2 = type> 
    point2d_base(std::enable_if_t<t2 == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    template<point_type t2 = type> 
    explicit point2d_base(std::enable_if_t<t2 != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

Ceci est le code que je préfère écrire, mais je obtenir beaucoup, beaucoup d'erreurs de compilation si je le fais comme ceci:

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    point2d_base(std::enable_if_t<type == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    explicit point2d_base(std::enable_if_t<type != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

Pour des raisons de référence, point_type est une « classe Enum » qui contient trois valeurs: generic, corner, center.

Ma question est: Pourquoi le premier code compile, et le second ne le compile pas?

Répondre

1

Vous ne pouvez pas compter sur vos paramètres de classe de modèle pour utiliser std::enable_if. Si vous souhaitez utiliser std::enable_if avec une fonction, vous devez faire de cette fonction une fonction modèle. C'est parce que lorsque le template de classe est instancié, toutes les fonctions membres de cette classe sont également instanciées. Vous avez besoin d'une fonction de membre de modèle pour activer cette fonction de manière conditionnelle ou non. (C'est ma conjecture et je pense est correct)

+0

Existe-t-il une version correcte du code qui est plus proche de ce que j'ai écrit dans le second exemple, où je n'ai pas besoin de redéclairer la variable 'type' autre chose? – Xirema

+0

Si vous voulez utiliser 'std :: enable_if', je ne pense pas. L'autre option basée sur vos besoins peut être la spécialisation de modèle. – MRB