2017-10-13 5 views
2

J'utilise le modèle de modèle curieusement récurrent pour un problème en C++. Dans certains cas utilisant la même méthode, je dois retourner une sous-classe ou une classe de base.La classe pour la méthode surchargée accepte le modèle et la classe de base - Comment définir une méthode par défaut?

ce cas la méthode décembre serait quelque chose comme

base& get() { 
return base_ref || deriv_ref; //depends on impl 
} 

alors que j'ai d'autres méthodes telles que

template <typename deriv> 
class base { 

void run(deriv& d) {//deriv specific method/derived class/} 
void run(base& b) { //base specific method// } 
} 

Cependant chaque fois que je retourne un derived class (qui est reinterperted comme base&) la valeur par défaut des méthodes à l'implémentation de la classe base comme indiqué ci-dessous.

template<typename d> 
struct base { 

    void run(d& type) { 
     std::cout << "deriv " << std::endl; 
    } 
    void run(base& type) { 
     std::cout << "base" << std::endl; 
    } 
    base& alter(d& der) { 
     return der; 
    } 
    d& no_alt(d& der) { 
     return der; 
    } 
}; 
struct deriv : public base<deriv> { 

}; 
int main() { 
    deriv foo; 
    base<deriv> bar; 
    bar.run(foo);   //prints deriv 
    bar.run(bar);   //print base 
    bar.run(bar.alter(foo));//print base (Need this to print deriv) 
    bar.run(bar.no_alt(foo));//print deriv 

} 

Comment puis-je avoir la valeur par défaut de méthode à la derived_methods dans ces cas?

En outre, je pense que le compilateur devrait donner un avertissement mal défini (car il a essentiellement deux méthodes qui acceptent le même type).

+0

Je ne suis pas sûr de comprendre votre question, mais de ce que je peux voir, il n'y a pas d'erreur avec la sortie –

+0

Hey je voulais dire par les méthodes ci-dessus pour être par référence et non par valeur, question devrait être logique maintenant. –

Répondre

1

alter renvoie le type base&. Cela signifie que l'instruction bar.run(bar.alter(foo)); va évaluer bar.alter(foo), ce qui renvoie une référence à foo cast comme . Ensuite, bar.run() est appelée avec cette référence base&.

Vous ne recevez pas d'avertissement, car vous avez donné la fonction base& et une seule surcharge prend base&. Si vous voulez que ce code particulier pour appeler la surcharge deriv& de run, vous devez changer la surcharge base& à quelque chose comme ceci:

void run(base& type) { 
    deriv* derivTest = dynamic_cast<deriv*>(&type); 
    if(derivTest != nullptr) 
     run(*derivTest); 
    else 
     std::cout << "base" << std::endl; 
} 

Ce vérifie si la référence adoptée en est vraiment une référence à deriv et appels le bon run si nécessaire. Notez que passer par un type de pointeur empêche une exception dans le cas où le dynamic_cast échoue.

+0

Hey désolé, je voulais dire pour ces méthodes d'être par référence pas de valeur, la question devrait avoir un sens maintenant. –

+0

Je mettrai à jour ma réponse, mais le compilateur verra toujours une fonction sortant un type 'base &' et choisira la surcharge 'base &' de la fonction. Si vous voulez que 'run' agisse différemment pour les objets' deriv & 'dans ce cas, alors vous devrez effectuer un' dynamic_cast' et voir si cela échoue. –