Erreurs, bugs, questions - page 1856

 

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Caractéristiques du langage mql5, subtilités et astuces

fxsaber, 2017.04.14 11:40

Ouaip, des courtiers véreux. Ils y mettaient aussi des nombres négatifs.

Il serait bon que les développeurs fixent une limite à l'éventail des valeurs possibles de chaque paramètre lorsque les courtiers configurent les symboles.

 

J'ai remarqué que lorsque je mets à jour des produits du marché, tous les paramètres de ce produit sur les graphiques sont réinitialisés aux valeurs par défaut.

Ce n'est pas bien, comment éviter cela ?

 

ArrayMaximum() et ArrayMinimum() - l'ordre dans lequel les paramètres sont passés ne correspond pas à l'aide :


 
fxsaber:
Un peu de savoir-faire. Contournement de l'opérateur d'affectation

Résultat

Ce n'est pas une astuce, c'est une perversion.

Je ne m'attendais pas à ça de ta part.

 
Koldun Zloy:

Ce n'est pas un truc intelligent, c'est une perversion.

Je ne m'y attendais pas de ta part.

Alors c'est pour vous

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Bibliothèques : TypeToBytes

fxsaber, 2017.04.13 13:34

Un exemple de l'utilité de cette fonction pour identifier les erreurs potentielles.

Écrire et exécuter le script.

#include <TypeToBytes.mqh>

struct STRUCT
{
  int i;
  
  STRUCT() : i(0) {}
  
  template <typename T>
  void operator =( T& ) {}
};

#define  PRINT(A) ::Print(#A + " = " + (string)(A));

void OnStart()
{
  PRINT(_WRONG_ASSIGN_OPERATOR(STRUCT))
}


Résultat.

_WRONG_ASSIGN_OPERATOR(STRUCT) = true

Cela indique que l'opérateur d'affectation ne copiera pas la structure dans une structure du même type.


Si nous ajoutons plus à la structure,

  void operator =( STRUCT &Value ) { this.i = 0; }

le résultat sera le même.


Il peut sembler qu'en changeant cet opérateur en

  void operator =( STRUCT &Value ) { this.i = Value.i; }

mais la bibliothèque dit le contraire.


C'est peut-être le point le plus subtil de cet exemple.

Corrigez-le en

#include <TypeToBytes.mqh>

struct STRUCT
{
  int i;
  
  STRUCT() : i(0) {}
  
  template <typename T>
  void operator =( T& ) {}

  void operator =( const STRUCT &Value ) { this.i = Value.i; }
};

#define  PRINT(A) ::Print(#A + " = " + (string)(A));

void OnStart()
{
  PRINT(_WRONG_ASSIGN_OPERATOR(STRUCT))
}

et vous obtenez le résultat

_WRONG_ASSIGN_OPERATOR(STRUCT) = false


Maintenant l'opérateur de copie est correct !

Nous pouvons vérifier de la même manière l'exactitude des opérateurs de cession/copie de toute structure simple.

 

1. Quand on écrit comme ça :

STRUCT StructCopy1 = Struct;
Ce n'est pas operator= qui doit être appelé mais le constructeur de copie.

Mais c'est plutôt une question pour les méta-citations.

2. Si le constructeur de copie créé par le compilateur n'est pas appelé, nous pouvons l'écrire nous-mêmes.

struct STRUCT
{
  int i;
  
  STRUCT(){}
  STRUCT( int _i ) : i(_i){}
  STRUCT( const STRUCT& other )
  {
      i = other.i;
  }
  
  void operator =( const STRUCT& )
  {
    this.i = 5;
  }
};

Maintenant, operator= n'est pas appelé.

3. Puisque les membres de la structure sont à notre disposition, nous pouvons simplement l'écrire de cette façon :

StructCopy1.i = Struct.i;

Mais si vous les rendez privés, alors votre tiphook ne vous aidera pas non plus.

4. et le plus important : operator= est utilisé pour s'assurer que toutes les affectations passent par lui et ne le contournent pas.

En général, le constructeur de copie est défini en même temps que lui.

Oui. J'ai regardé l'échantillon. Je n'ai pas vu beaucoup de bénéfices.

 
Koldun Zloy:

1. Quand on écrit comme ça :

Ce n'est pas operator= qui doit être appelé mais le constructeur de copie.

Mais c'est plutôt une question pour les méta-citations.

2. Si le constructeur de copie créé par le compilateur n'est pas appelé, nous pouvons l'écrire nous-mêmes.

Maintenant, operator= n'est pas appelé.

3. Puisque les membres de la structure sont à notre disposition, nous pouvons simplement l'écrire de cette façon :

Mais si vous les rendez privés, alors votre tiphook ne vous aidera pas non plus.

4. et le plus important : operator= est utilisé pour s'assurer que toutes les affectations passent par lui et ne le contournent pas.

En général, le constructeur de copie est défini en même temps que lui.

Oui. J'ai regardé l'échantillon. Je n'ai pas vu beaucoup de bénéfices.

Lifehack contourne également le constructeur de copie. Et l'avantage est là
#include <TypeToBytes.mqh>

struct STRUCT
{
  int i;
  
  STRUCT(){}
  STRUCT( int _i ) : i(_i){}
  STRUCT( const STRUCT& other )
  {
      i = 2;
  }
  
  void operator =( const STRUCT& )
  {
//    Print(__FUNCSIG__);
    
    this.i = 5;
  }
};

void OnStart()
{
  STRUCT Struct(1);  

  ArrayPrint(_R(Struct).Bytes); // 1 0 0 0
  
  STRUCT StructCopy1 = Struct;  // STRUCT( const STRUCT& )

  ArrayPrint(_R(StructCopy1).Bytes); // 2 0 0 0
    
  StructCopy1 = Struct;         // void STRUCT::operator=( const STRUCT& )

  ArrayPrint(_R(StructCopy1).Bytes); // 5 0 0 0
}

_R est une chose universelle. C'est pourquoi nous n'avons pas besoin de redéfinir les structures extraterrestres avec leurs propres opérateurs.

#include <TypeToBytes.mqh>

struct STRUCT
{
  int i;
  
  void operator =( const STRUCT& )
  {
    this.i = 5;
  }
};

void OnStart()
{
  STRUCT Structs[] = {{1}, {2}};
  
  ArrayPrint(_R(Structs).Bytes); // 1 0 0 0 2 0 0 0
}
 
Andrey Dik:

Oui, avec Akepad je vois que l'encodage est Win-1251 (ANSI), mais les anciens fichiers ont UTF-16LE 1200.

L'encodage par défaut pour les nouveaux fichiers a-t-il finalement changé ?

Non, c'était toujours Win-1251 (ANSI) et UTF a été ajouté à un moment donné. Mais seulement pour les fichiers sources qui contiennent des caractères non-Ansi.
 
Andrey Khatimlianskii:
Non, c'était toujours Win-1251 (ANSI) et à un moment donné, UTF a été ajouté. Mais seulement pour les sources qui contiennent des caractères non-Ansi.
Je vois. Merci.
 

Et comment surcharger les opérateurs [] et =, de sorte que vous pouvez écrire comme ceci :

class A
{
private:
   int arr[5];
};

A *obj = new A();

for(int i = 0; i < 5; ++i)    obj[i] = i;