2009-05-30 6 views
2

Je voudrais écrire deux fonctions distinctes pour gérer une valeur constante et une variable d'un type donné (à savoir, int).«F (5)» et «int x; F (x) »pour appeler différentes fonctions?

est ici le cas de test exemple:

int main(void) { 
     int x=12; 
     F(5); // this should print "constant" 
     F(x); // this should print "variable" 
} 

Je pensais que ce serait suffisant pour définir:

void F(int v) { cout << "constant\n"; } 
void F(int& v) { cout << "variable\n"; } 

Cela suppose que le compilateur choisira int& pour les variables comme « mieux spécialisé » et int pour les constantes comme seul choix). Cependant, ce G++ est le résultat:

test.cc: In function ‘int main()’: 
test.cc:13: error: call of overloaded ‘F(int&)’ is ambiguous // for line: F(x); 
test.cc:4: note: candidates are: void F(int) 
test.cc:5: note:     void F(int&) 

G++ ne choisit F(int) pour les constantes, mais ne sait pas quelle fonction de choisir des variables.
Est-ce que quelqu'un a une idée de ce qui se passe?

Contexte: J'expérimente des méthodes d'unification de type prologue en C++. Être capable de connaître la différence entre les constantes et les variables m'aiderait à choisir le comportement d'unification souhaité (affectation ou comparaison) dans des cas tels que functor(x,5) <=> functor(3,5).

Répondre

16

Si vous souhaitez faire la différence entre une constante de temps de compilation et une constante de temps non compilée, vous n'avez aucune chance. Ce n'est pas possible. Mais si vous voulez faire la différence entre une variable non constante et une variable constante (et tout le reste inclus - comme des littéraux), vous pouvez surcharger une fonction avec un paramètre de référence constant et non constant. Pour ce scénario, le standard C++ introduit des règles supplémentaires qui rendent ce cas par ailleurs ambigu.

void f(int const&); // #1 
void f(int&);  // #2 

Dans cette affaire, les décisions suivantes sont faites

int x = 0; 
int const y = x; 
int const z = 1; 

f(1); // #1 
f(x); // #2 
f(y); // #1 
f(z); // #1 

Notez comment il ne peut pas la différence entre y et z, même si la valeur de z est une constante de temps de compilation (appelée expression constante intégrale ou ICE), tandis que y ne l'est pas. Ce que peut faire est de n'accepter que les valeurs de temps de compilation. Surcharge la fonction de sorte que celui-ci est un modèle et l'autre n'est pas

template<int N> void f(); // #1 
void f(int n);   // #2 

Il se comporte comme celui-ci alors:

int x = 0; 
int const y = x; 
int const z = 1; 

f<1>(); // #1 
f(1); // #2 
f<y>(); // error, y not an ICE 
f<z>(); // #1 
f(x); // #2 
+0

Et ce qui est probablement ce que je avais besoin. Je vous remercie. – liori

+0

Oui, ceci (le f (int const) et f (int &)) était ce dont j'avais réellement besoin. Merci beaucoup! – liori