3 votes

Surcharge d'une fonction modèle qui peut faire la différence entre une méthode membre non statique et d'autres fonctions.

struct A // some class
{
  void method(); // non-static member method
  static void function(); // static member method
};
void function(); // global function
vector<A> vi; // any such `std` like container

Je veux avoir une fonction (disons Iterate() ) qui peut être appelé de la manière suivante :

Iterate(vi, &A::method);  // (1)
Iterate(vi, &A::function); // (2a)
Iterate(vi, &function); // (2b)

(2a) et (2b) sont tout simplement identiques.

Maintenant Iterate() Le prototype ressemble à ce qui suit pour (1) et (2) :

template<typename Container, typename Method>
void Iterate (Container &container, Method method); // for (1)

template<typename Container, typename Function>
void Iterate (Container &container, Function function); // for (2a), (2b)

Naturellement, les deux sont exactement les mêmes, ce qui entraîne une erreur de compilation.
Existe-t-il un moyen de surcharger/spécialiser Iterate() dans C++03 qui permettra aux deux fonctions de coexister ?

1voto

Nawaz Points 148870

Vous pourriez rendre une fonction plus spécifique que l'autre :

template<typename Container, typename Functor>
void Iterate (Container &container, Functor fun); 

template<typename Container, typename R, typename ..Args>
void Iterate (Container &container, R (Container::value_type::*fun)(Args...));

Le premier modèle fonctionnerait pour les fonctions ordinaires, les objets-fonctions et les fonctions membres statiques, tandis que le second ne fonctionnerait que pour les fonctions membres non statiques.

En C++03, vous pouviez simuler un modèle variadique en écrivant des surcharges comme indiqué ici :

template<typename Container, typename R>
void Iterate (Container &container, R (Container::value_type::*fun)());

template<typename Container, typename R, typename Arg>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg));

template<typename Container, typename R, typename Arg1, typename Arg2>
void Iterate (Container &container, R (Container::value_type::*fun)(Arg1, Arg2));

//add more overloads to handle member functions 
//that take 3 or more arguments

Bien sûr, si vous devez les mettre en œuvre différemment. Par exemple, la syntaxe pour invoquer la fonction membre sera (obj.*fun)(a1,a2,a3); tandis que la syntaxe d'invocation du foncteur est juste fun(a1,a2,a2) . Je ne sais cependant pas quels arguments vous passeriez à la fonction (membre ou foncteur). Je suppose que ce n'est pas le vrai code, vous voulez juste explorer la syntaxe.

Un point important est que obj (du conteneur) est no nécessaire pour invoquer le foncteur, vous pouvez le passer comme argument à celui-ci, cependant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X