타자에 대한 질문 - 페이지 4

 
Ilya Malev :

문제가 무엇인지 명확하지 않습니다. 개체의 초기화를 Init() 유형의 별도 메서드, 아마도 가상 메서드로 이동하는 것이 가능하지 않습니까?

물론 가능합니다. class.get_int()/class.get_double()/class.get_string()/... ?))를 수행하는 것이 가능하지 않습니까? 스타일, 습관...

 
pavlick_ :

물론 가능합니다. class.get_int()/class.get_double()/class.get_string()/... ?))를 수행하는 것이 가능하지 않습니까? 스타일, 습관...

가능합니다. 그러면 double d, var[]; d=var[x] 대신 d=var[x].get_double을 작성하십시오. 우리가 마조히즘에 참여한다면, 집합적으로 =))

 
Ilya Malev :

즉, 결국 주제는 입력 작업(암시적 포함)을 오버로드하는 가능성을 mql에 도입하려는 바람으로 요약됩니다. 즉, 메서드 호출의 컨텍스트를 결정하고 예상되는 반환 값의 유형에 따라 이 컨텍스트에서 원하는 코드를 호출합니다.

이것은 분명히 C++ 표준이 아니며 일반적으로 C++의 장점(MQL 개발자가 기본으로 취함) - C++에서는 프로그래머가 명시적으로 처리할 수 없는 모든 것이므로 포인터와 자신의 typedef 작성

그게 다야, 포인터는 또한 아프리카에 메모리 주소에 대한 포인터입니다. 항상 매개변수로 전달하고 함수의 결과로 가져올 수 있고 포인터를 역참조할 수 있습니다. 바이트 메모리의 물리적 값을 가져오고 포인터를 캐스팅합니다. 새로운 유형으로 - 많은 바이트의 메모리를 얻습니다)))

MQL에서 포인터는 이유를 말하기 어렵지만 포인터가 있습니다. 개발자는 데이터 보호가 우선 순위이므로 "샌드박스"를 넘어설 수 있는 모든 혁신이 제외됩니다.



주제에 대해 불행히도 템플릿( template ) 작업에 대한 연습이 거의 없지만 다음과 같이 수행할 수 있다고 생각합니다.

1. 결과적으로 필요한 유형을 반환하는 여러 오버로드된 함수를 작성하고 이 유형을 매개변수로 사용합니다. 그래서:

 //+------------------------------------------------------------------+
int f( const int x)
  {
   return (( int ) 1 );
  };
//+------------------------------------------------------------------+
double f( const double x)
  {
   return (( double ) 2 );
  }
//+------------------------------------------------------------------+
string f( const string x)
  {
   return (( string ) 3 );
  }
//+------------------------------------------------------------------+
void OnStart ()
  { 
   int     a= 0 ;
   double b= 0 ;
   string c= "0" ;
   a = f(a);
   b = f(b);
   c = f(c);
   Print ( "a = " ,a);
   Print ( "b = " ,b);
   Print ( "c = " ,c);
}

2. 이제 f() 함수를 템플릿으로 래핑하고 x 매개변수를 숨겨야 합니다. 템플릿에서 이 작업을 수행할 수 있으면 호출은 a=f()가 됩니다. 시각적으로 모든 것이 입력하는 것처럼 아름답습니다.

 
Igor Makanu :

이것은 분명히 C++ 표준이 아닙니다.

나는 당신이 틀렸다고 생각합니다. "순수한"C ++로 오랫동안 작성하지 않았지만 네트워크에는 이와 같은 코드의 예가 가득합니다.

 class A
{
public :
     operator int () const ;
};

A:: operator int () const
{
     return 0 ;
}
 
Ilya Malev :

나는 당신이 틀렸다고 생각합니다. "순수한"C ++로 오랫동안 작성하지 않았지만 네트워크에는 이와 같은 코드의 예가 가득합니다.

이러한 예제는 올바르게 작동하지만 복잡한 유형 이면 어떻게 될까요? - 구조 또는 배열? C ++에서 이것은 해당 유형에 대한 포인터를 사용하여 해결되었으며 컴파일러는 물리적으로 메모리 주소를 반환했으며 포인터를 역참조하면 데이터에 대한 올바른 작업이 보장되었습니다.

 
Igor Makanu :

이러한 예제는 올바르게 작동하지만 복잡한 유형 이면 어떻게 될까요? - 구조 또는 배열? C ++에서 이것은 해당 유형에 대한 포인터를 사용하여 해결되었으며 컴파일러는 물리적으로 메모리 주소를 반환했으며 포인터를 역참조하면 데이터에 대한 올바른 작업이 보장되었습니다.

mql에서 이 예제는 불행히도 제대로 작동하지 않습니다.

복잡한 유형, 구조체 또는 배열 자체는 필요한 모든 것을 오버로드할 수 있으며 캐스트 오버로드가 필요하지 않습니다...

 
Ilya Malev :

mql에서 이 예제는 불행히도 제대로 작동하지 않습니다.

글쎄, 네, 방금 봤습니다. 유형 변환을 오버로드하려는 MQL 도움말은 오버로드가 허용되고 단항 연산은 각각 단항 및 이진으로만 오버로드된다고 명시되어 있습니다. 행렬 작업을 수행하고 오버로드를 시도했습니다. ^ - 작동하지 않습니다.해야했습니다! 사용:

  • 바이너리 +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=, &=,|=,^=,<<=,>>=,&&,||,&,|,^;
  • 단항 +,-,++,--,!,~;
  • 할당 연산자 =;
  • 인덱싱 연산자 [].


내 예를 다시 살펴보았습니다. 컴파일러는 내 예를 템플릿 으로 래핑할 수 없지만 숫자만 반환할 수는 없지만 예를 들어 return((1/x) - 매개변수 x로 문자열을 제공할 수 있습니다. string , 일반적으로 컴파일 단계에서 모든 C 컴파일러는 유형의 적합성을 확인하고 MQL은 모호한 솔루션이 템플릿에 래핑되는 것을 허용하지 않습니다.

IMHO, 귀하의 작업은 1개의 주제 게시물입니다. MQL에서는 모든 오버로드된 함수를 설명해야만 올바르게 해결할 수 있습니다. 그런 다음 컴파일 단계에서 전달 및 반환되는 모든 유형의 변수와 오버로드된 모든 함수가 확인됩니다.

 
Igor Makanu :

글쎄, 네, 방금 보았습니다. 유형 변환을 오버로드하려는 MQL 도움말은 오버로드가 허용되고 단항 연산은 각각 단항 및 이진으로만 오버로드된다고 명시되어 있습니다. 행렬 작업을 수행하고 오버로드를 시도했습니다. ^ - 작동하지 않습니다.해야했습니다! 사용

^ 가 오버로딩을 허용하지 않는 상황은 없다고 99% 말할 수 있지만 ! 준다. 그리고 오버로딩의 가능성은 연산자의 유형에 의존하지 않습니다. 당신은 뭔가를 잘못 이해했습니다. 이 예를 여기에 게시하십시오. 이미 잊어버리고 점수를 매긴 경우에는 물론 그렇지 않습니다.)

연산자 유형에 대해 내가 만난 유일한 제한은 논리 연산자 ==, !=, ! 및 = 포인터에 적용될 때(any_type * ). 올바른 오버로딩을 위해서는 자동 개체 또는 구조로 작업해야 합니다. 최근 몇 달간 이 칩에 개를 잔뜩 먹어서 자신있게 말할 수 있어요 :)

 
Ilya Malev :

^ 가 오버로딩을 허용하지 않는 상황은 없다고 99% 말할 수 있지만 ! 준다. 그리고 오버로딩의 가능성은 연산자의 유형에 의존하지 않습니다. 당신은 뭔가를 잘못 이해했습니다. 이 예를 여기에 게시하십시오. 이미 잊어버리고 점수를 매긴 경우에는 물론 그렇지 않습니다.)

연산자 유형에 대해 내가 만난 유일한 제한은 논리 연산자 ==, !=, ! 및 = 포인터에 적용될 때(any_type * ). 올바른 오버로딩을 위해서는 자동 개체 또는 구조로 작업해야 합니다. 최근 몇 달간 이 칩에 개를 잔뜩 먹어서 자신있게 말할 수 있어요 :)

 #include <Math\Alglib\linalg.mqh>
class Matrix
  {
public :
   CMatrixDouble     M;
   int                row; //m_strok;
   int                col; //n_stolb;
   void               Matrix( void )         {                             }
   void               Matrix( int m, int n)  { M.Resize(m,n); row=m;col=n; }
   //----      умножение матриц
   Matrix operator *( const Matrix &B){Matrix res( this .row,B.col);CAblas::RMatrixGemm( this .row,B.col, this .col, 1.0 , this .M, 0 , 0 , 0 ,B.M, 0 , 0 , 0 , 0 ,res.M, 0 , 0 ); return (res);  }
   //----      транспонирование матрицы
   Matrix operator !( void ){Matrix res( this .col, this .row);CAblas::RMatrixTranspose( this .row, this .col, this .M, 0 , 0 ,res.M, 0 , 0 ); return (res);                             }
   //----      нулевая матрица
   void               zeros( int r, int c) { this .M.Resize(r,c); this .row=r; this .col=c; for ( int i= 0 ;i<r;i++){ for ( int j= 0 ;j<c;j++){ this .M[i].Set(j, 0.0 );}}               }
   //----      вывод в журнал матрицы
   void MatrixPrint( string   separator= "|" , uint digits= 3 ){ string s,sep= " " +separator+ " " ; for ( int i= 0 ;i<row;i++){s=separator; for ( int j= 0 ;j<col;j++) s+= DoubleToString (M[i][j],digits)+sep; Print (s); Sleep ( 123 );}}
private :
   void               Matrix( const Matrix &R) { this =R;                                                                                                            }
  };

행렬에 대한 "고전적인" 작업에서는 ^ 연산자를 사용하여 행렬을 전치해야 합니다. 여기에 제 예가 있습니다. Matlab에서 SSA 방법을 이식했습니다. 이것은 CMatrixDouble을 기반으로 하는 행렬의 가장 간단한 곱셈, 할당 및 전치입니다. 이것은 저장하는 행렬의 크기(행과 열의 수)를 알지 못하므로 클래스에서 래핑해야 했습니다.

 
추신, 즉, 이항 연산자를 단항(2항을 1항으로)으로 오버로드하고 싶었지만 물론 그렇지 않습니다. 유일한 예외는 []