2017-04-22 2 views
1

Ma tâche consiste à implémenter ma propre fonction std :: ref. Je sais qu'il existe un foncteur reference_wrapper, qui aide à std :: ref. Mais comment pourrais-je implémenter ces fonctions/classes. Je pense à ce qui suit:Comment fonctionne C++ 11 std :: ref?

template <class T> 
struct myreference_wrapper{ 
    T& functor; 
    myreference_wrapper(T& t):functor(t){} 
    void operator()('parameter') { 
     functor('parameter'); 
    }; 
}; 

template<class T> 
myreference_wrapper<T> myref(T& t){ 
    myreference_wrapper<T> functor(t); 
    return functor; 
} 

Quand nous appelons myref, nous ne pouvons pas utiliser les paramètres du modèle, car std :: ref ne pas utiliser les paramètres du modèle. Mais quand nous appelons operator(), nous devons connaître ses paramètres, car nous voulons les transmettre à l'opérateur du foncteur() (je l'ai signé avec 'parameter'). Comment std :: ref le fait sans aucun paramètre de template?

+0

Vous pourriez essayer de spécialiser 'myreference_wrapper' pour les types' Callable'. – Holt

+1

Depuis quand 'std :: ref' n'utilise-t-il pas les paramètres du template? – InternetAussie

+1

Pourquoi voulez-vous réinventer la roue et ne pas utiliser 'std :: ref'? – zett42

Répondre

2

Les fonctions de modèle peuvent déduire les arguments de modèle des types auxquels la fonction est appelée. Par exemple:

template <class T> T min(T a, T b) { 
    return a < b ? a : b; 
} 

Lorsque vous appelez cette fonction vous n'avez pas besoin de préciser les arguments de modèle:

int x = min(1, 2); 

Le compilateur examine les types des arguments de la fonction, voit qu'ils sont tous les deux int , et conclut qu'il doit appeler min<int>.

Même chose pour un appel à votre fonction de modèle myref:

int i; 
myref(i); 

Encore une fois, le compilateur regarde le type de l'argument de la fonction, voit qu'il est int, et conclut qu'il doit appeler myref<int>. En outre, la fonction min ci-dessus peut être un peu plus compliquée à utiliser. min(1, 2.0) ne compilera pas, car les deux types d'arguments de fonction sont différents; l'un est int et l'autre est double, donc il n'y a pas de T qui correspond exactement aux deux. Il y a plusieurs solutions possibles ici. La première consiste à réécrire la fonction de modèle de manière à avoir deux arguments de type template au lieu d'un: template <class T0, class T1> ??? min(T0, T1). Cela conduit à un problème de conception: quel est le bon type de retour? Une autre solution consiste à changer le code appelant pour passer des arguments du même type. Et encore une autre consiste à donner explicitement le type d'argument template: min<int>(1, 2.0). Ce code dit d'appeler min<int>, qui prend deux arguments de type int; le double sera converti en int, comme il le ferait pour une fonction non-template qui prend deux valeurs int.

+1

Je pense que la question de OP concerne l'objet 'reference_wrapper' à' Callable', qui fournit un opérateur 'operator()' et OP demande comment il peut récupérer les arguments (et le type de retour) pour cet 'operator()' 'std :: ref' ne les utilise pas. – Holt