mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 138

 
fxsaber :
 // Некоторые возможности структур, которых нет у классов.

흠, 흥미롭네요. 저는 const 필드가 있는 아이디어가 정말 좋았습니다. const는 한 번만 초기화됩니다.

 
Igor Makanu :

흠, 흥미롭네요. 저는 const 필드가 있는 아이디어가 정말 좋았습니다. const는 한 번만 초기화됩니다.

이제 다음과 같이 로트를 정규화할 수 있습니다.

클래스에서 상수 멤버 를 선언할 수도 있습니다.

 
Andrey Barinov :

클래스에서 상수 멤버 를 선언할 수도 있습니다.

글쎄, 예, 여기 일반적으로 모든 수식어를 실제로 사용하지 않습니다. 그래서 감탄을 불러 일으켰습니다. 확인했습니다. 이제 코드를 난독 화했습니다. 단지 간결하게 작성하고 싶었지만 )))

 #property strict
//+------------------------------------------------------------------+
class NL
  {
#ifndef SID #define SID(v) SymbolInfoDouble ( _Symbol ,v)
private : const class sl
     {
   public : double      s,b,l; int d;sl():s(SID( SYMBOL_VOLUME_STEP )),b(SID( SYMBOL_VOLUME_MAX )),l(SID( SYMBOL_VOLUME_MIN )){; long i= 10000000 ,k= long (s/ 0.0000001 );d= 0 ; while (d< 7 && k%i> 0 ){i/= 10 ;d++;}} #endif
     }
   param; public :   double Lot( double value){ return ( NormalizeDouble ( fmax ( fmin (param.s* round (value/param.s),param.b),param.l),param.d));}
  }
Normalize;
//+------------------------------------------------------------------+
void OnStart ()
  {
   double l = 0.0 ;
   for ( int i= 0 ;i< 10 ;i++)
     {
      l+= 0.005 ;
       Print (Normalize.Lot(l));
     }
  }
//+------------------------------------------------------------------+
추신: ME에서 접는 것만으로는 충분하지 않습니다! - 마우스 휠을 여기저기 돌리기 위해 힘을 가합니다(((
 

MQL을 사용하여 각 구성에 대한 나의 구현.

지금까지는 배열에서만 작동합니다. 1) 표준 mql-arrays; 2) [](int) 연산자가 정의되어 있어야 하는 사용자 정의 배열 클래스와 오버로드된 전역 함수 ArraySize .

통사론:

 foreach(element_var, array)  { ... }

배열은 변수와 표현식으로 모두 설정할 수 있습니다. 이 때문에 정원을 울타리로 묶어야 했습니다. 표현식은 한 번 실행되어 배열에 대한 포인터를 저장한 다음 이 포인터로 액세스합니다.


 #define TEMPL(T) template < typename T>


enum E_TRUE  { __TRUE= 1 };
enum E_FALSE { __FALSE= 0 };

TEMPL(T) E_TRUE  __IsMqlArray(T&[], int ) { return true ; }
TEMPL(T) E_FALSE __IsMqlArray(T&, int )   { return false ; }
TEMPL(T) E_FALSE __IsMqlArray(T, uint )   { return false ; }

#define IS_MQL_ARRAY(var)  ( typename (__IsMqlArray(var, 0 ))== typename (E_TRUE) )


static
class __CForeachHelper
{
 public :
  TEMPL(T)
   class __CDummyArr { public : T data[]; };
  TEMPL(T)
   struct __TValue { public :  T data;  __TValue(T value) { data= value; } };
   
  TEMPL(T) T*    Ptr(T* a) { return a; }
  TEMPL(T) T*    Ptr(T& a) { return &a; }
  TEMPL(T) __CDummyArr<T>* Ptr( const T&[])  { return NULL ; }
  
  TEMPL(T) __TValue<T>     Obj( const void * p, T)               { return (T)p; }
  TEMPL(T) __CDummyArr<T>* Obj( const void * p, __CDummyArr<T>*) { return (__CDummyArr<T>*)p; }
}
__foreachhelper;


#define __ARR_ITEM(ptr, array, i)  (IS_MQL_ARRAY(array) ? array[i] : __foreachhelper.Obj(ptr,   0 ?__foreachhelper.Ptr(array) : NULL ).data[i])

#define __ARR_SIZE(ptr, array) (IS_MQL_ARRAY(array) ? ArraySize (array) : ArraySize (__foreachhelper.Obj(ptr,   0 ?__foreachhelper.Ptr(array) : NULL ).data))


#define CONCAT(a, b) a ##b

#define CONCAT2(a, b) CONCAT(a, b)


#define __FORVAR(var) CONCAT2(__for ##var, __LINE__ )


#define foreach(element, array) \
   if ( 0 ) { class __CForeachArrCheck \ // Проверка наличия конструктора у элемента mql-массива
           { public : TEMPL(T) void f(T&){}  TEMPL(T) void f(T*){}  TEMPL(T) void f(T* const &[]){}  TEMPL(T) void f(T const &[]) { T arr[ 1 ]; } \           
           } _fcheck;  _fcheck.f(array); \
         } \
   else \
   for ( int __FORVAR(state)= 1 ;  __FORVAR(state)== 1 ; ) \
   for ( const void * __FORVAR(ptr)=__foreachhelper.Ptr(array);  __FORVAR(state)== 1 ; ) \
     for ( int __FORVAR(i)= 0 , __FORVAR(count)=__ARR_SIZE(__FORVAR(ptr), array);  __FORVAR(state)--== 1 && __FORVAR(i)<__FORVAR(count);  __FORVAR(i)++) \
       for (element=__ARR_ITEM(__FORVAR(ptr), array, __FORVAR(i));  __FORVAR(state)== 0 ;  __FORVAR(state)= 1 )


사용 예:

 template < typename T>
class CArr
{ 
 public : 
  T data[];
  T     operator []( int i)   const { return data[i]; }
   void operator =(T const &arr[]) { int size= ArraySize (arr);   ArrayResize (data, size);   for ( int i= 0 ; i<size; i++) data[i]=arr[i]; }
};


template < typename T>
int ArraySize ( const CArr<T> &arr) { return ArraySize (arr.data); }


class A { public : double value;  A( double val= 0 ) { value=val; } };


CArr< int >* GetArr() { Print ( "Get Array" );   static int arr[]={ 10 , 20 , 30 };   static CArr< int > Arr= arr;   return &Arr; }


void OnStart ()
{
   Print ( "Test 1" );
   double arr[]= { 10 , 20 , 30 };
            
  foreach( double val, arr) Print (val);
       
   Print ( "Test 2" );
  CArr< double > arr2 = arr;
       
  foreach( double val, arr2) Print (val);

         
   Print ( "Test 3" );
  A _a( 10 ), _b( 20 ), _c( 30 );
  A* arr3[ 3 ];
  arr3[ 0 ]=&_a;  arr3[ 1 ]=&_b;  arr3[ 2 ]=&_c;
       
  foreach(A* a, arr3) Print (a.value);

   Print ( "Test 4" );
  CArr<A*> arr4 = arr3;

  foreach(A* a, arr4) Print (a.value);


   Print ( "Test 5" );

  foreach( int a, GetArr()) Print (a);
}
 
Alexey Navoykov :

사용 예:

조금 다시 썼다

   //void operator=(T const &arr[]) { int size=ArraySize(arr);  ArrayResize(data, size);  for (int i=0; i<size; i++) data[i]=arr[i]; }
   void operator =(T const &arr[]) { ArrayResize (data, ArrayCopy (data, arr)); }
 
Alexey Navoykov :

MQL을 사용하여 각 구성에 대한 나의 구현.

지금까지는 배열에서만 작동합니다. 1) 표준 mql-arrays; 2) [](int) 연산자가 정의되어 있어야 하는 사용자 정의 배열 클래스와 오버로드된 전역 함수 ArraySize .

멋지게 나왔다! 그런 옵션을 만들 수 있습니까?

 void OnStart ()
{
   MqlTick Ticks[ 3 ];
  
   for ( int i = 0 ; i < ArraySize (Ticks); i++)
    Ticks[i].bid = i + 1 ;

  foreach( MqlTick Tick, Ticks) Print (Tick.bid); // OK
    
  foreach( MqlTick Tick[ 1 ], Ticks) ArrayPrint (Tick); // 'Tick' - invalid array access   
}
 
fxsaber :

멋지게 나왔다! 그런 옵션을 만들 수 있습니까?

변수를 사용하여 배열을 잘 초기화하는 것은 MQL에서 지원되지 않습니다. 배열 요소에 할당할 수 있습니다.

foreach(Ticks[0], Ticks) ArrayPrint (Ticks[0].bid);

 
Alexey Navoykov :
변수를 사용하여 배열을 잘 초기화하는 것은 MQL에서 지원되지 않습니다. 배열 요소에 할당 할 수 있습니다.

나는 구현을 알아내지 못했지만 그렇게 하는 것이 요점을 알지 못합니다.


이 옵션은 작동하지 않습니다

 void f( const int &Array[] )
{
   foreach ( int val, Array) Print(val);
}
 
fxsaber :

이 옵션은 작동하지 않습니다.

네 확실합니다. 이해하기 시작하면서 흥미로운 기능을 발견했습니다. 상수 유형의 인수(예: const int )를 템플릿에 전달할 때 단순히 T = int 로 처리되지만 constness도 어떻게든 고려되므로 혼란스럽습니다.
 template < typename T>
class B { };

template < typename T>
void f(T & a)
{ 
  B< const T> b;     // OK. Значит T==int
  const T arr[]={}; // Тоже всё ОК.
  T arr2[];         // 'arr2' - 'const' variable must be initialized.  wtf?
} 

void OnStart ()
{
   const int a= 0 ;
  f(a);
}

처음에는 MQL의 기능인 줄 알았는데 C++에서도 마찬가지입니다.

 
Alexey Navoykov :

처음에는 MQL의 기능인 줄 알았는데 C++에서도 마찬가지입니다.

유형이 const int이기 때문입니다. 템플릿에서 문제 없이 앞에 const를 첨부할 수 있다는 것입니다.

그러나 C++에서 간단한 조작으로 유형에서 const를 제거할 수 있는 경우 mql에서는 이를 수행할 수 없습니다.