10
votes

Devrais-je utiliser des fonctions ou des foncteurs apatrides?

Ces 2 morceaux de code font la même chose. Et il sera utilisé dans la fonction de tri comme vous pouvez le voir. Ce qui est mieux? J'écris habituellement ce dernier. Mais j'ai vu des codeurs le faire comme l'ancien. XXX PRE>

et P>

std::sort(wordvector.begin(), wordvector.end(), val_lt);


3 commentaires

Le plus simple que le travail est le meilleur.


Vous n'avez pas mentionné sur quels critères les alternatives devraient être jugées. Il y a plusieurs situations dans lesquelles est «meilleur» que l'autre ... mais en général, oui, prenez le plus simple. N'oubliez pas le C ++ 1x Lambdas si vous envisagez d'une autre alternative.


Dupliqué possible de Pourquoi utiliser des fonctions sur les fonctions?


6 Réponses :


5
votes

Le premier est appelé un objet fonction et est utile si vous devez transmettre des informations de contexte à la fonction de comparaison. La fonction autonome ne reçoit que x et y et n'a pas la possibilité de transporter un contexte.

Dans l'instance spécifique ci-dessus, les deux méthodes d'écriture de la fonction de comparaison sont à peu près équivalentes.


0 commentaires

-2
votes

Les deux seront également rapides. Différence presque négligeable.

Lorsque vous utilisez le fonctionnement, cela signifie que la fonction opérateur () a trois paramètres dans le code généré par le compilateur, premier paramater est un pointeur sur le VAL_LT L'objet lui-même, et les deuxième et troisième paramètres sont les paramètres que vous avez mentionnés dans la signature. Quelque chose comme ceci: xxx


1 commentaires

Sauf que l'opérateur () dans le foncteur est inlincé



1
votes

Je préférerais probablement la première en règle générale, mais préférerais généralement utiliser un modèle: xxx

utilisation de .seconde limite le degré de généricité , mais vous obtenez toujours un peu (par exemple, si la mémoire sert, boost :: tuple fournit un .first et .seconde pour les tuples de deux éléments. En règle générale, être un modèle donne une petite assurance que le compilateur sera en mesure de générer le code en ligne, donc si vous vous souciez de l'efficacité, cela pourrait aider un peu (ou cela pourrait ne pas, mais il est peu probable que jamais aucun mal).


0 commentaires

0
votes

Je dirais, choisissez le plus simple qui fonctionne pour votre cas particulier. Dans ce cas, choisissez deuxième sur le premier.


0 commentaires

1
votes

Si vous voulez être capable de également appeler la fonction dans une autre partie de votre code et non passé en fonction du fonctionnement, préférez le formulaire de fonction. Par exemple, vous préféreriez: xxx

à xxx

sinon lors du choix du formulaire de foncteur, vous feriez mieux d'appeler avec un objet de foncteur sans nom . C'est: xxx

au lieu de: xxx

paramètres de nuit et les valeurs de retour permettent facilement au compilateur d'optimiser. Il fait référence à un concept global appelé RVO (optimisation de la valeur de retour). Dans ce cas, il libérera probablement votre code d'une construction de copie.


2 commentaires

Baumes: En fait, étant donné que l'objet est apatride, le compilateur éliminerait probablement la construction elle-même complètement.


@Matthieu M. Merci, merci, n'a pas eu pensé cela du tout. Venir de Sophia? J'ai étudié là .. :-)



7
votes

La raison pour laquelle vous voyez certaines personnes préférez la première version est que les foncteurs peuvent être trivialement inlinés.

Lorsque vous passez un foncteur sur std :: Trier , le type de foncteur est connu de la fonction, et la fonction exacte à appeler est donc connue à l'heure de la compilée et peut être trivialement inlinité .

avec une fonction simple, quel std :: Trier est vraiment un pointeur de fonction et à la compilation qui ne dit rien sur quel fonctionne. Donc, cela ne peut pas être inliné à moins que le compilateur effectue une analyse de flux assez étendue pour voir où le pointeur est venu de dans cet appel spécifique . Et cela fera certainement cette optimisation dans un petit exemple comme le vôtre, mais si le pointeur de foncteur / fonction a été transmis comme un argument de fonction d'ailleurs, par exemple, ou s'il était lu dans une structure de données intermédiaire avant d'être transmis à Std :: Trier , alors, le compilateur peut ne pas être capable de faire connecter la version du pointeur de fonction, et cela finirait donc plus lentement.


0 commentaires