7
votes

Surcharge de la fonction externe pour une utilisation dans un module séparé

Je veux faire Ce (supporté par Ceci ), mais je frappe un problème minuscule (arrosé pour votre non-tête-tête-non-méparasture).

Disons que je suis un écrivain de la bibliothèque et que j'ai ces fonctions dans un fichier D: xxx

Et j'ai un code client dans un autre module dans lequel je tente de surcharger exécuter et appelez runrun : xxx

ceci Code Résultats dans 'JiggyPuff!' ' Être imprimé plutôt que 'wiggytuff!', ce qui a du sens, car la définition de runrun ne peut voir que le formulaire non spécifié non spécifié disponible dans son module. Cependant, je (et le code client) aimerait voir un «wiggytuff» plutôt qu'un «jiggypuff».

in c ++ je jette un espace de noms mod_a {...} < / Code> autour de la spécialisation de la course Pour montrer que la course du code client doit être examinée à côté de mon code de bibliothèque lors de la tentative de détermination de la définition de Runrun appels, accueillant la boîte de vers qui est venu avec telle Comportement.

Y a-t-il un point D Idiomatic d'organiser cela tel que la fonction exécuter peut être intentionnellement détournée? Plus précisément, je voudrais imiter la manière dont les fonctions globales de C ++ se comportent avec des spécialisations ad hoc.

d

8 commentaires

Votre deuxième exécuté (t) ne surcharge pas mod_a.run (t) du tout, vous n'êtes pas dans le même module.


@Kris oui, tu as raison. J'étais abusant de la terminologie. L'intention est que la réponse me montre comment je voudrais le pousser dans l'ensemble des surcharges que le compilateur vérifie lors de l'examen runrun .


Mon commentaire était de vouloir dire pourquoi cela ne devrait pas (et ne devrait pas fonctionner, selon dlang.org/hijack .html ). Je ne pense pas que votre utilisation de la terminologie était fausse de quelque manière que ce soit.


@Kris j'ai lu cet article avant de poster cette question et le problème est subtilement différent: les ensembles de surcharge sont en cours de vérification dans le code du client (toutes les surcharges connues lors du traitement du fichier), je veux ici modifier la manière dont les surcharges sont déterminées en générique / Code de la bibliothèque Modèle (toutes les surcharges ne sont pas connues lors du traitement du fichier). Mon wiggytuff exécuter appel n'est même pas apparaissant dans son propre ensemble de surcharge sur la définition runrun Définir Parallèlement à d'autres ensembles de surcharge, et je veux que cette situation change.


Je reçois le sentiment que nous essayons de décrire la même situation à ce que nous ressentons comme nous ne réussissons pas :) De toute façon, j'aimerais cette question parce que c'est un cas d'avance (que je n'avais pas pensé à) et je suis très intéressé à trouver ceux-ci et à trouver des moyens de traiter avec eux. Malheureusement, je n'ai pas encore pu compilé quoi que ce soit qui finit par travailler comme si vous le souhaitez, la façon dont vous l'aimeriez.


@Kris aye, je suis copacetique avec cette évaluation.


Le du client n'a pas pu être appelé par mod_a.runrun de toute façon, car la version du client ne prend aucun argument. Je suppose que c'est juste une faute de frappe?


@ J.Miller Ayep. C'était une faute de frappe. Fixé.


3 Réponses :


2
votes
//untested

module mod_a;
import std.stdio;
void run(T)(T v) if (!is(T : double)) { writeln("Jigglypuff!"); }
void runrun(T)(T v) { run(v); }

import mod_a;
void run(T)() if (is(T : double)) { writeln("Wigglytuff!"); }
void main() { runrun(1.0); }

1 commentaires

Même si runrun peut voir la version spécialisée de exécuter , n'y a-t-il pas une inadéquation de paramètres? Le SPÉCIALISÉ Accepte 0 Paramètres et RUNRUN l'appelle avec 1.



1
votes

Dans cet exemple, vous êtes l'auteur de la bibliothèque mod_a de sorte qu'il serait relativement facile de le modifier. Mais je ne peux pas m'empêcher de penser à la situation où vous n'êtes pas l'auteur de la bibliothèque.

Dans ce cas, l'auteur actuel de la bibliothèque serait probablement soit heureux que vous ne puissiez pas simplement faire ce que vous essayez de faire ... ou ne veut pas participer activement à ce que vous essayez de faire.

suppose que l'auteur de la bibliothèque veut que vous puissiez "détourner" une fonction qu'il utilise dans sa mise en œuvre. Il ou elle irait probablement à ce sujet différemment; Je voudrais.

Ceci est un domaine où je crois que les histoires d'encapsulation que vous avez liées et que je viens de lire, décrivez exactement comment réaliser la situation opposée de ce que vous voulez ici. Ce type de chose hurle qu'il faut une programmation contractuelle.

En tant qu'auteur de bibliothèque, je vous proposerais probablement une interface et éventuellement une classe abstraite, peut-être même une ou deux implémentations concrètes, que vous pourriez utiliser pour faire votre chose. Quelqu'un d'autre peut donner à ajouter un modèle ou un paramètre d'exécution nécessitant une implémentation spécifique comme argument. Pourtant, quelqu'un d'autre pourrait ajouter un délégué de string paresseux au mélange.

(Ma) Conclusion: En tant qu'auteur de bibliothèque, il existe des options pour faire ce que vous voulez possibles. Si ce n'est pas possible avec votre bibliothèque préférée, vous finirez probablement de classer une demande de fonctionnalité.


2 commentaires

Aye, je pose cette question du point de vue en tant qu'écrivain de la bibliothèque. Placer une modification de la modification ...


D'accord. Le système de modules de S est spécialement conçu pour éviter cela, pour de très bonnes raisons. Donc, dans la conception d'une bibliothèque, il est préférable de permettre aux clients d'insérer des implémentations, car @kris dit, via des interfaces, des successions ou des fonctions d'ordre supérieur. Par exemple. Une surcharge de runrun qui prend une fonction exécuter est un modèle ou un paramètre régulier.



0
votes

J'ai trouvé une manière étrange de le faire en utilisant des mixines pour déplacer l'espace de noms recherché à partir du code de bibliothèque au code de l'utilisateur. Du point de vue de l'écrivain de la bibliothèque, il s'agit d'une fonction supplémentaire et d'un type de modèle supplémentaire; Du point de vue de l'utilisateur, c'est une ligne de code supplémentaire (un peu gênante) à côté d'un appel de fonction supplémentaire par instance d'un type avec des «méthodes» globales en dehors de son module. Considérant qu'il s'agit d'une façon de remplacer explicitement une fonctionnalité de langue, je pense em> c'est plutôt bon.

import mod_a;
import wrappers;

mixin wrapmix; ///< magic

void main() {
  double val = 1.0;
  runrun(wrap(val)); ///< note the 'wrap' call
}


0 commentaires