2010-05-15 4 views
0
class RunAround; 
class HopUpAndDown; 
class Sleep; 

template<typename Acts> int doThis(); 
template<> int doThis<RunAround>() { /* run run run.. */ return 3; } 
template<> int doThis<HopUpAndDown>() { /* hop hop hop.. */ return 2; } 
template<> int doThis<Sleep>()  { /* zzz.. */ return -2; } 

struct Results 
{ 
    template<typename Act> int& operator()() 
    { 
     static int result; 
     return result; 
    } 
}; 



int main() 
{ 
    Results results; 
    //results<RunAround>() = doThis<RunAround>(); 
    results.operator()<RunAround>() = doThis<RunAround>(); 
    results.operator()<Sleep>() = doThis<Sleep>(); 
    return 0; 
}; 

Si je supprime le commentaire, le compilateur pense que je fais appel operator() en classe modèle non Results<RunAround> quand je existant veux operator<RunAround>() en classe Results.Comment appeler une surcharge d'un opérateur basé sur un modèle sans utiliser le mot 'opérateur'?

Si je veux continuer à utiliser une surcharge d'opérateur au lieu d'un nom normal, suis-je condamné à utiliser la syntaxe terrible sous le commentaire (qui fonctionne)?

+0

Je recommande vraiment ce qui en fait une fonction nommée 'get'. – GManNickG

Répondre

1

La chose la plus confortable est de laisser le travail de déduction argument modèle pour vous:

struct Results { 
    template<typename Act> int& operator()(Act) { /* ... */ } 
}; 

results(RunAround()) = /* ... */; 
+2

Mais cela ajoute le surcoût d'instancier un objet, en passant un paramètre, et nécessitant une définition de RunAround au lieu d'une simple déclaration forward ... – Kyle

+0

Le surcoût est trivial à optimiser pour le compilateur (du moins si le constructeur ne le fait pas avoir des effets secondaires sur des objets externes). Quant à la nécessité d'une définition: si vous sélectionnez un modèle pour ce type, je suppose que vous voulez probablement faire quelque chose avec lui de toute façon. Il n'y a que deux choix ici: soit vous utilisez l'argument déduction, soit vous spécifiez explicitement le paramètre template. –

+0

Ou vous pouvez juste l'envelopper dans une classe vide. Comme 'results (identité ()) = ...;' changement de votre paramètre à 'template int & operator() (identité ) {...}' –