ça s'appelle du type erasure et c'est faisable avec std::function et std::bind ou les lambdas.
#include <iostream>
#include <functional>
int a(int) { return 1; }
int b(int, double) { return 2; }
int c(int, bool, int) { return 3; }
using func = std::function<int (int)>;
int main() {
func fa = a;
func fb = std::bind(b, std::placeholders::_1, 10.0);
func fc = std::bind(c, std::placeholders::_1, false, 666);
func fx = [] (int) -> int { return 0; };
return 0;
}
Par contre, si ta fonction est surchargée (possède le même nom) c'est plus chiant, il faut faire un cast explicit. Certains proposent une solution élégante ressemblante à qOverload de Qt.
- Edité par markand 10 mai 2019 à 16:23:48
git is great because Linus did it, mercurial is better because he didn't.
Pourquoi crois tu que l'on parle systématiquement de pointeur de fonction ???
C'est parce que, à l'inverse de n'importe quel types de donnée, (mais au même titre que n'importe quelle variable), une fonction a forcément une adresse mémoire.
Et c'est logique, au point que tu aurais pu trouver la réponse par toi-même en y réfléchissant un tout petit peu, vu que, même si une fonction ne fait strictement rien, il faut pouvoir l'exécuter si tu y fait appel.
Cela se remarque d'ailleurs très bien lorsque tu demandes au compilateur de s'arrêter à la génération du code assembleur, car un code proche de
void foo(){
}
int main()
{
foo();
}
va se traduire en assembleur par quelque chose qui serait proche de
Observes les lignes 3 à 5, 20 à 22 et surtout 30 du résultat que l'on obtient:
La ligne 3 indique (faisons simple, même si ce n'est pas tout à fait juste, à l'éditeur de liens )que "_Z3foov" est un identifiant qui devra être connu depuis "n'importe où" (globl ==>"global")
la ligne 4 indique (à l'éditeur de liens, toujours) que "_Z3foov" n'est pas une donnée, mais que c'est une fonciton
la ligne 5 va poser un "jalon" qui permettra à l'éditeur de liens de savoir ... à quelle adresse mémoire commence la fonction identifiée par _Z3foov.
Les lignes 20 à 22 font exactement pareil pour l'identifiant "main"
Enfin, la ligne 30 indique explicitement qu'il faut faire appel à la fonction qui commence ... au jalon identifié par "_Z3foov".
Au final, la réponse que tu cherches est que tu ne peux pas créer un alias sur ce qui sera considéré comme "une fonction à appeler" autrement que sous la forme d'un pointeur de fonction.
Quand la notion de pointeur (de référence voire même de constance) s'avère optionnelle, comme dans les cas suivants
using int_ptr = int *; //int_ptr est considéré comme étant un POINTEUR SUR int
using int_ref = int &; //int_ref est considéré comme étant une REFERENCE SUR int
using int_const = int const; // int_const est considéré comme étant un int CONSTANT
tu peux l'ajouter, si tu en as besoin (et même au besoin les combiner ) sous la forme de
using int_const_ref = int const &; //int_const_ref est considéré comme étant une REFERENCE CONSTANTE SUR int
Mais si la notion de pointeur est -- par nature -- obligatoire, tu ne peux pas envisager de la supprimer!
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Un très grand merci à tous les gens qui sont venus aider sur ce fil.
using , fonction int vers int
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
git is great because Linus did it, mercurial is better because he didn't.