打字问题

 

亲爱的程序员,我为一个问题困惑了很久。有没有可能以某种方式设计并使函数的返回值隐式化?因此,一个类的方法 将返回一个不同类型的值,如果调用方法在外部上是相同的。

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;  
 }  

这是班级本身,你不用看了,如果问题很清楚的话。

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;
 };
 

你也可以在分配时摆脱swich,利用重载能力。

   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;
   }

那么,如果返回值要用于算术动作(这样就有东西可以参考),那就差不多了。

   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");

---

如果是为了我自己,我会制作重载函数,通过引用参数来返回。

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

你也可以在分配时摆脱swich,利用重载能力。

那么,如果返回值将用于算术动作(这样就有东西可查了),那就差不多了。

有了明确的重载和算术动作,它就很清楚了。是的,在这种情况下,重载=显然更好,你是对的,我只是为一个问题快速建立了一个例子,并没有真正想过这个问题(虽然有一些不仅是int,还有char、ucar、short、ushort、uint、bool和color,所以不是所有东西都是简单的))))))))。

德米特里-费多塞耶夫

如果我让重载函数的参数以引用方式返回。


这里的问题是,重载方法 的返回值的类型取决于对象的内容。

例如,我们有一个多类型的数组(我就不举例了,因为有很多书)。当然,任何数组都必须有[]的索引操作,它可以返回具有适当索引的变量的值。

但变量有不同的类型。这个索引下可能有数据时间或字符串或其他用户定义的类型。而且最理想的是,我希望在索引[]时,返回值类型能自动输出适当的类型,而不需要显式地将其参数化。我曾经这样解决这个 "问题":var[(char)1]、var[(short)1]、var[(uint)1]等,但这些拐杖都不起作用。

 
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:

在这种情况下,不可能将p1分配给p4(类型改变),而这在原则上应该是可能的。

或者在数组的情况下--不同类型的对象有一个基本类型,但是数组对象本身有一个方法,其返回类型取决于对象类型和相应的索引。
 
一个类似的问题:为什么当重载一个方法时(在重载的方法 签名中),不出现返回类型,只出现参数类型,也就是说,你不能用不同的返回类型定义两个相同的方法。
 
Ilya Malev:

在这种情况下,你不能把p1分配给p4(类型改变),这在原则上应该是可能的。

或者在数组的情况下--不同类型的对象有一个基本类型,但是数组对象本身有一个方法,其返回类型取决于对应索引的对象的类型。

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

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

是的,在90%的情况下,传输32个字节,而4个就够了......无论如何,这不是这个主题的重点,我感兴趣的是目的--可能有人在描述的情况下找到了或多或少的优雅解决方案。


p.s. 此外,这个问题根本不是在一个对象/结构中存储不同类型的数据。

 
Ilya Malev:
一个类似的问题:为什么当重载一个方法时(在重载的方法 签名中)不显示返回类型,只显示参数类型。即你不能定义两个相同的方法,但有不同的返回类型。

该方法不能决定返回什么类型。

 
fxsaber:

一个方法不能决定返回什么类型。

嗯,换句话说,你重复了我写的东西。问题不在于它能不能,而在于它为什么不能,以及如何优雅地绕过它。

 
Ilya Malev:

好吧,换句话说,你已经重复了我写的东西。问题不在于它是否能或不能,而在于它为什么不能,以及如何优雅地绕过它。

类型控制丢失。通过C++资源查看这些问题的答案。我认为他们经常被问到。

原因: