Frage zum Tippen

 

Liebe Programmiererinnen und Programmierer, ich habe lange über eine Frage gegrübelt. Ist es möglich, die implizite Typisierung des Rückgabewerts einer Funktion irgendwie zu erreichen und durchzuführen? Damit eine Methode einer Klasse einen Wert eines anderen Typs zurückgibt, wenn die aufrufenden Methoden äußerlich identisch sind.

void OnStart()
 {
  CParameter p1 = Ask, p2 = Bid, p3 = TimeCurrent(), p4 = TimeLocal();
  
  // Перегруженный в CParameter оператор ~ возвращает преобразованное в строку значение известного объекту типа
  
  printf( "p1=%s, p2=%s, p3=%s, p4=%s", ~p1, ~p2, ~p3, ~p4 );
  
  // А можно ли исхитриться и сделать вот так (допустим это будет перегруженный тем или иным образом оператор !, возвращающий
  //   значение нужного типа в зависимости от type. 
  //
  // double ask = !p1, bid = !p2;
  // datetime current = !p3, local = !p4;  
 }  

Das ist die Klasse selbst, man muss sie sich nicht ansehen, wenn die Frage klar ist.

enum TYPE{ NUMBER, PRICE, TIME };

class CParameter
 {
public:
  template<typename T> void operator= ( T par )
   {
    if( typename( T ) == "double" )
     {
      data = int( double( par ) * 100000 );
      type = PRICE;
     }
    else
     {
      if( typename( T ) == "datetime" )
       {
        data = int( uint( par ) );
        type = TIME;
       }
      else
       {
        data = int( par );
        type = NUMBER;
       }
     }
   }
   
  double to_price()
   {
    switch(type)
     {
      case PRICE: return double( data ) / 100000;
      case TIME:  return MathArcsin(2.0);
      default:    return double( data );
     }
   }

  datetime to_time()
   {
    switch(type)
     {
      case TIME:  return datetime( data );
      default:    return 0;
     }
   }

  int to_number()
   {
    switch(type)
     {
      case PRICE: return int( double( data ) / 100000 );
      case TIME:  return 0;
      default:    return data;
     }
   }
   
  string to_string()
   {
    switch(type)
     {
      case PRICE: return DoubleToString( to_price(), 5 );
      case TIME:  return TimeToString( to_time(), TIME_DATE|TIME_SECONDS );
      default:    return IntegerToString( data );
     }
   }
   
  string operator~ ()
   {
    return to_string();
   }
   
private:
  int data;
  TYPE type;
 };
 

Sie können auch swich bei der Zuweisung loswerden und die Vorteile der Überlastungsmöglichkeiten nutzen:

   void operator=(double par){
      data = int(double(par)*100000 );
      type = PRICE;
   }
   void operator=(datetime par){
      data=int(uint(par));
      type=TIME;
   }
   void operator=(int par){   
      data = int(par);
      type = NUMBER;
   }

Wenn der Rückgabewert dann für eine arithmetische Aktion verwendet werden soll (damit es etwas gibt, auf das man sich beziehen kann), ist es ungefähr dasselbe:

   string operator+(string par){
      return to_string()+par;
   }
   
   double operator+(double par){
      return to_price()+par;
   }   
   
   double operator+(int par){
      return to_number()+par;
   }  
Print(p1+1);
Print(p1+1.0);
Print(p1+"1");

---

Wenn für mich selbst, würde ich überlastete Funktionen mit Rückgabe über Parameter per Referenz zu machen.

   void r(double & v){
      v=to_price();
   }
   void r(int & v){
      v=to_number();
   }   
   void r(string & v){
      v=to_string();
   }   
 
Dmitry Fedoseev:

Sie können auch swich bei der Zuweisung loswerden und die Vorteile der Überlastungsmöglichkeiten nutzen:

Wenn der Rückgabewert dann für eine arithmetische Aktion verwendet wird (so dass es etwas zum Nachschlagen gibt), ist es ungefähr dasselbe:

Mit expliziten Überladungen und arithmetischen Aktionen ist es so klar wie es ist. Ja, überladen = eindeutig besser in diesem Fall, Sie haben Recht, ich war nur schnell ein Beispiel für eine Frage zu bauen und nicht wirklich darüber nachgedacht (obwohl es nicht nur int, sondern auch char, uchar, short, ushort, uint, bool und Farbe, so dass nicht alles einfach ist )))))))).

Dmitry Fedoseev:

Wenn ich überladene Funktionen mit Parameterrückgabe per Referenz machen würde.


Das Problem dabei ist, dass der Typ des Rückgabewertsder überladenen Methode vom Inhalt des Objekts abhängt.

Wir haben zum Beispiel ein Array mit mehreren Typen (ich werde keine Beispiele nennen, da es eine Menge Bücher gibt). Und natürlich muss jedes Array über die Indexierungsoperation [] verfügen, die den Wert einer Variablen mit einem entsprechenden Index zurückgibt.

Aber Variablen haben unterschiedliche Typen. Unter diesem Index kann datetime oder string oder ein anderer benutzerdefinierter Typ stehen. Und im Idealfall möchte ich, dass der Rückgabewert-Typ beim Indizieren von [] automatisch den entsprechenden Typ erzeugt, ohne dass er explizit parametrisiert werden muss. Ich pflegte dieses "Problem" auf diese Weise zu lösen: var[(char)1], var[(short)1], var[(uint)1] usw., aber diese Krücken funktionieren nicht.

 
void OnStart()
 {
  CParameter<double> p1 = Ask;
  CParameter<double> p2 = Bid;
  CParameter<datetime> p3 = TimeCurrent();
  CParameter<datetime> p4 = TimeLocal();
  
  // Перегруженный в CParameter оператор ~ возвращает преобразованное в строку значение известного объекту типа
  
  printf( "p1=%s, p2=%s, p3=%s, p4=%s", ~p1, ~p2, ~p3, ~p4 );
  
  // А можно ли исхитриться и сделать вот так (допустим это будет перегруженный тем или иным образом оператор !, возвращающий
  //   значение нужного типа в зависимости от type. 
  //
   double ask = !p1, bid = !p2;
   datetime current = !p3, local = !p4;  
 }  
template <typename T>
class CParameter
 {
public: 
  void operator =( const T Value )
  {
    this.data = Value;
  }

  string operator~( void) const
   {
    return((string)this.data);
   }
   
  T operator !( void ) const
  {
    return(this.data);
  }  
   
private:
  T data;
 };
 
fxsaber:

In diesem Fall können Sie p1 nicht p4 (mit Typwechsel) zuordnen, was im Prinzip möglich sein sollte.

Oder im Falle eines Arrays - Objekte verschiedener Typen mit einem Basistyp, aber das Array-Objekt selbst hat eine Methode, deren Rückgabetyp vom Objekttyp mit dem entsprechenden Index abhängt
 
eine ähnliche frage: warum erscheint beim überladen einer methode (in der signatur der überladenen methode) nicht der rückgabetyp, sondern nur die parametertypen. d.h. man kann nicht zwei identische methoden mit unterschiedlichen rückgabetypen definieren. warum diese einschränkung? was ist der sinn, warum kann man eine methode nicht mit dem rückgabetyp identischer parameter überladen?
 
Ilya Malev:

In diesem Fall können Sie p1 nicht p4 zuordnen (mit einer Typänderung), was im Prinzip möglich sein sollte.

Oder im Falle eines Arrays - Objekte verschiedener Typen mit einem Basistyp, aber das Array-Objekt selbst hat eine Methode, deren Rückgabetyp vom Typ des Objekts mit dem entsprechenden Index abhängt

https://www.mql5.com/ru/docs/constants/structures/mqlparam

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура входных параметров индикатора
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура входных параметров индикатора
  • www.mql5.com
каждого элемента этого массива указывает тип данных, передаваемых данным элементом. Сами значения параметров индикатора необходимо предварительно поместить в соответствующие поля каждого элемента (в...
 

Ja, 32 Bytes zu übertragen, obwohl in 90% der Fälle 4 Bytes ausreichen... Wie auch immer, das ist nicht der Punkt dieses Threads, ich interessiere mich für den Zweck - vielleicht hat jemand eine mehr oder weniger anmutige Lösung für die beschriebene Situation gefunden


p.s. Außerdem geht es bei der Frage gar nicht darum, verschiedene Datentypen in einem Objekt/einer Struktur zu speichern.

 
Ilya Malev:
eine ähnliche frage: warum erscheint beim überladen einer methode (in der signatur der überladenen methode) nicht der rückgabetyp, sondern nur die parametertypen. d.h. man kann nicht zwei identische methoden mit unterschiedlichen rückgabetypen definieren. warum wird diese einschränkung gemacht? was ist der sinn, warum kann man eine methode nicht nach rückgabetyp mit identischen parametern überladen

Die Methode kann nicht entscheiden, welchen Typ sie zurückgeben soll.

 
fxsaber:

Eine Methode kann nicht entscheiden, welchen Typ sie zurückgibt.

Mit anderen Worten: Sie haben wiederholt, was ich geschrieben habe. Die Frage war nicht, ob es geht oder nicht, sondern warum es nicht geht und wie man es elegant umgehen kann.

 
Ilya Malev:

Mit anderen Worten, Sie haben wiederholt, was ich geschrieben habe. Die Frage war nicht, ob sie es kann oder nicht, sondern warum sie es nicht kann und wie man das Problem elegant umgehen kann.

Die Schriftkontrolle geht verloren. Suchen Sie in den C++-Ressourcen nach Antworten auf diese Fragen. Ich glaube, sie werden ziemlich oft gefragt.

Grund der Beschwerde: