Generische Klassenbibliothek - Bugs, Beschreibung, Fragen, Nutzungsmöglichkeiten und Vorschläge - Seite 20

 
Sergey Dzyublik:

1. Beseitigen Sie zweideutiges Verhalten:
Wenn wir "INT_MAX - 10" als Parameter an CPrimeGenerator::ExpandPrime übergeben, wird das Ergebnis "INT_MAX" zurückgegeben.
Wenn wir "INT_MAX - 10" als Parameter an CPrimeGenerator::GetPrime übergeben, wird das gleiche Ergebnis zurückgegeben: "INT_MAX - 10".

In beiden Fällen handelt es sich bei dem zurückgegebenen Wert nicht um eine Primzahl, was den Benutzer in die Irre führt.

Zum ersten Punkt:

Hier gibt es keine Zweideutigkeit.

Die Methode GetPrime sollte die nächstgelegene Primzahl von oben zurückgeben, aber auf dem Intervall von INT_MAX - 10 bis INT_MAX gibt es keine, deshalb wird INT_MAX - 10 zurückgegeben.

Die ExpandPrime-Methode verdoppelt zunächst den Eingabewert, und die GetPrime-Methode wird anhand der erhaltenen Zahl aufgerufen.

Darüber hinaus verfügt ExpandPrime über eine Prüfung auf INT_MAX-Überschreitung:

   if((uint)new_size>INT_MAX && INT_MAX>old_size)
      return INT_MAX;
   else
      return GetPrime(new_size);

Meiner Meinung nach ist die Logik, die hinter dem Verhalten dieser Methoden steht, absolut eindeutig und richtig.


Was den zweiten und dritten Punkt betrifft:

Die von Ihnen vorgeschlagenen Änderungen sind größtenteils nur für Randprobleme relevant, wenn die CHashMap sehr groß ist. Es gibt jedoch keine Garantie dafür, dass sie sich positiv auf die Leistung auswirken. Daher müssen separate Studien durchgeführt werden, um die Richtigkeit der von Ihnen vorgeschlagenen Änderungen zu ermitteln.

 
Roman Konopelko:

Hier gibt es keine Zweideutigkeit.
Die Methode GetPrime sollte die nächstgelegene Primzahl von oben zurückgeben, aber es gibt keine zwischen INT_MAX - 10 und INT_MAX, also wird INT_MAX - 10 zurückgegeben.
Die ExpandPrime-Methode verdoppelt zunächst den Eingabewert, und die GetPrime-Methode wird anhand der erhaltenen Zahl aufgerufen.
Darüber hinaus verfügt ExpandPrime über eine Prüfung auf INT_MAX-Überschreitung:
Die Logik des Verhaltens dieser Methoden ist absolut eindeutig und korrekt.


1. Die Funktionen können unbekannte Zahlen anstelle von Primzahlen zurückgeben.
Wie ein Benutzer diese Daten verwendet, ist sein Problem, vielleicht wirft er sie in den Long und gibt sie an die Supercomputing-Funktionen weiter, wen interessiert das schon.
Es kann nämlich sein, dass wir etwas anderes zurückgeben als das, was deklariert ist und von den Funktionen standardmäßig erwartet wird.

2. Wie können wir überprüfen, ob der Funktionsaufruf eine Primzahl und nicht etwas anderes zurückgegeben hat?
Sie können ihn nicht einfach mit INT_MAX vergleichen.
Sie müssen sie mit der letzten verfügbaren Primzahl vergleichen, die kleiner als INT_MAX ist.
Jedes Mal, wenn man das Ergebnis der Aufrufe dieser Funktionen mit einer magischen Zahl vergleicht, um sicherzustellen, dass alles in Ordnung ist, finde ich das absurd.

 
Sergey Dzyublik:

1. Die Funktionen dürfen keine Primzahlen zurückgeben, sondern nur obskure Zahlen.
Wie der Benutzer diese Daten verwendet, ist sein Problem, vielleicht gibt er sie in long ein und übergibt sie dann an Supercomputing-Funktionen, wen interessiert das schon.
Es kann nämlich sein, dass wir etwas anderes zurückgeben als das, was deklariert ist und standardmäßig von den Funktionen erwartet wird.

2. Wie können wir überprüfen, ob der Funktionsaufruf eine Primzahl und nicht etwas anderes zurückgegeben hat?
Sie können ihn nicht einfach mit INT_MAX vergleichen.
Sie müssen sie mit der letzten verfügbaren Primzahl vergleichen, die kleiner als INT_MAX ist.
Das Ergebnis jedes Aufrufs dieser Funktionen jedes Mal mit einer magischen Zahl zu vergleichen, um sicherzustellen, dass alles korrekt ist, klingt für mich absurd.

1. Ihr Fall, in dem Sie mit der GetPrime-Methode eine nicht einfache Zahl erhalten, ist der einzige, der mir bisher begegnet ist. Dieser Vorfall wird behoben, indem die Prüfung bei der Erzeugung von Primzahlen geändert wird:

//--- outside of our predefined table
   for(int i=(min|1); i<=INT_MAX; i+=2)
     {
      if(IsPrime(i) && ((i-1)%s_hash_prime!=0))
         return(i);
     }
   return(min);

2. Die Methode CPrimeGenerator::IsPrime wird verwendet, um die Zahl der Einfachheit halber zu überprüfen

 

Versucht, von meiner ArrayList zu Ihrer zu wechseln, die in Generic/ArrayList.mqh ist

ME gibt nach "." nichts mehr an.

Wie erhalte ich den Wert? Get() und [] fehlen in der Klasse.

Dabei wird nicht berücksichtigt, dass es eine Reihe von Zeigern geben könnte.

Und wer erstellt diese Bibliothek?

Hier ist meine Version von ArrayList aus Java:

Dateien:
ArrayList.mqh  46 kb
 
Als ich diese Variante erstellt habe, gab es keine Klassenvorlagen.
 
Roman Konopelko:

Damit generische Sammlungen korrekt mit Klassenobjekten funktionieren, müssen diese Klassen die Schnittstelle IEqualityComparable implementieren, in der die Methoden Equals und HashCode definiert sind. Das bedeutet, dass der Benutzer Berechnungsmethoden für Hash-Codes festlegen muss, und das ist bisher die einzige Möglichkeit, da es unmöglich ist, diese Methoden automatisch zu implementieren, wie es beispielsweise in .Net mit Hilfe von MQL5 gemacht wurde.

Wenn nur Klassen, die von IEqualityComparable geerbt wurden, korrekt funktionieren, dann sollten wir die Arbeit mit anderen Typen auf Compiler-Ebene deaktivieren.

Ich möchte Sie an diesen Code erinnern:

//+------------------------------------------------------------------+
//| Returns a hashcode for custom object.                            |
//+------------------------------------------------------------------+
template<typename T>
int GetHashCode(T value)
  {
//--- try to convert to equality comparable object  
   IEqualityComparable<T>*equtable=dynamic_cast<IEqualityComparable<T>*>(value);
   if(equtable)
     {
      //--- calculate hash by specied method   
      return equtable.HashCode();
     }
   else
     {
      //--- calculate hash from name of object
      return GetHashCode(typename(value));
     }
  }

Ich glaube, diese Funktion sollte durch diese ersetzt werden:

template<typename  T>
int GetHashCode(IEqualityComparable<T> &value)
  {
    return value.HashCode()
  }
 
Alexey Navoykov:

Wenn nur Klassen, die von IEqualityComparable geerbt wurden, korrekt funktionieren, dann sollten Sie die Arbeit mit anderen Typen auf Compiler-Ebene verbieten.

Die Arbeit mit diesem Typ ist unbequem. Die GetHashCode-Überladungen für die Standardtypen zeigen die Schnittstelle zum Abrufen des Hashcodes.


Ärgerlich ist, dass sie nicht vorhanden ist.

template<typename T>
interface IEqualityComparable
  {
//--- method for determining equality
   bool              Equals(T & value);
//--- method to calculate hash code   
   int               HashCode(void);
  };


D.h. für Objekte, die jetzt nicht funktionieren.

 
fxsaber:

Es wäre schwierig, damit zu arbeiten. Die GetHashCode-Überladungen für Standardtypen zeigen die Schnittstelle zum Abrufen von Hash-Code.

Was ist jetzt praktisch? Die Tatsache, dass man bei der Übergabe eines Enums oder Zeigers einer Klasse, die die Schnittstelle nicht unterstützt, an diese Funktion nur den Klassennamen erhält? ) Und vor allem funktioniert der Code und lässt sich kompilieren, als ob alles normal wäre.

 
Alexey Navoykov:

Was ist jetzt die Bequemlichkeit? Dass die Übergabe eines Enums oder Zeigers einer Klasse, die die Schnittstelle nicht unterstützt, in diese Funktion, Sie erhalten nur den Klassennamen? Awesome hash ) Und am wichtigsten ist, der Code funktioniert, kompiliert, als ob alles normal war. Dies ist nicht der Fall.

Ja, sie haben einen Mist gebaut. Sie haben gedankenlos von NetFramework kopiert und eingefügt, obwohl es offensichtlich ist, dass es ohne Unterstützung für Schnittstellen auf Sprachebene nicht adäquat funktionieren kann. Ich erinnere mich noch an das Niveau der MQ-Codes vor 6-7 Jahren, und heute ist es im Vergleich zu damals miserabel.

 
Alexey Navoykov:

Wo ist jetzt der Komfort? Die Tatsache, dass man bei der Übergabe eines Enums oder eines Zeigers einer Klasse, die die Schnittstelle nicht unterstützt, an diese Funktion nur den Klassennamen erhält? Netter Hash ) Und am wichtigsten ist, dass der Code funktioniert und kompiliert, als ob alles in Ordnung wäre. Das ist nicht der Fall.

Ich stimme zu, es ist besser, sofort einen Kompilierungsfehler zu erhalten, als sich lange mit der Frage zu beschäftigen, warum es nicht funktioniert.

Um ehrlich zu sein, verstehe ich nicht einmal, warum sie dort eine Schnittstelle eingebaut haben. Schließlich brauchen Sie nur GetHashCode für den gewünschten Typ zu überladen und müssen nicht anfangen, IEqualityComparable zu erstellen.

Grund der Beschwerde: