#ifdef __cplusplus
#include <iostream>
#endif
#define PRINT(x) ; Print ( #x, ":" , string (x))
template < typename T>
class main_wrapper{
public :
T data;
};
template < typename T>
class external_wrapper{
public :
T data;
};
template < typename T>
class A{
public :
class internal_wrapper : public external_wrapper<T> {};
main_wrapper<internal_wrapper> internal_wrapper_0;
main_wrapper<external_wrapper<T>> external_wrapper_0;
A(){
main_wrapper<internal_wrapper> internal_wrapper_1;
main_wrapper<external_wrapper<T>> external_wrapper_1;
#ifdef __MQL5__
PRINT( __FUNCSIG__ );
PRINT( typename (internal_wrapper_0.data.data)); // (Bug) int int
PRINT( typename (external_wrapper_0.data.data)); // (OK) int B*
PRINT( typename (internal_wrapper_1.data.data)); // (Bug) int int
PRINT( typename (external_wrapper_1.data.data)); // (OK) int B*#endif
}
};
class B{
char data[ 10 ];
};
class C{
char data[ 1000 ];
};
voidOnStart ()
{
A< int > val_int;
A<B*> val_ptr;
printf ( "%d\n" , sizeof (main_wrapper<A<B>::internal_wrapper>)); // (Bug) 36 //sizeof(main_wrapper<A< int >::internal_wrapper>) is usedprintf ( "%d\n" , sizeof (main_wrapper<A<C>::internal_wrapper>)); // (Bug) 36 //sizeof(main_wrapper<A< int >::internal_wrapper>) is used
}
int main(){
OnStart ();
return1 ;
}
매우 불쾌한 MT5(빌드 2316) 버그가 추가 개발을 차단합니다. 내부 유형 "C"로 여러 번 래핑된 복잡한 객체를 생성하면 완전히 다른 데이터 유형 , 아마도 "B", 아마도 "int", 원하는 것이 무엇이든 ...
문제가 코드에 있는 것이 아니라 MQL 컴파일러의 작업에 있다는 것을 파헤치고 이해하는 데 많은 시간과 노력을 기울였습니다. (C++ 온라인: https://onlinegdb.com/H1R1fR5ML ) 아마도 문제는 컴파일 타임에 코드를 생성할 때 템플릿 클래스 "main_wrapper"의 캐시에 있고 내부 클래스 "internal_wrapper"가 다양한 데이터 유형(int, B*, 나, 다). 어떤 첫 번째 데이터 유형이 템플릿 클래스 "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>에 의해 생성될 것이며, 이 데이터 유형은 향후 이 템플릿의 모든 개체에서 추가로 사용될 것입니다.
Sergey Dzyublik : 추가 개발을 차단하는 매우 불쾌한 버그. 내부 유형 "C"로 여러 번 래핑된 복잡한 객체를 생성하면 완전히 다른 데이터 유형 , 아마도 "B", 아마도 "int", 원하는 것이 무엇이든 ...
문제가 코드에 있는 것이 아니라 MQL 컴파일러의 작업에 있다는 것을 파헤치고 이해하는 데 많은 시간과 노력을 기울였습니다. (C++ 온라인: https://onlinegdb.com/H1R1fR5ML ) 아마도 문제는 컴파일 타임에 코드를 생성할 때 템플릿 클래스 "main_wrapper"의 캐시에 있고 내부 클래스 "internal_wrapper"가 다양한 데이터 유형(int, B*, 나, 다). 어떤 첫 번째 데이터 유형이 템플릿 클래스 "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>에 의해 생성될 것이며, 이 데이터 유형은 향후 이 템플릿의 모든 개체에서 추가로 사용될 것입니다.
템플릿 클래스 코드 생성과 관련된 또 다른 버그는 아래에 제공됩니다.
#ifdef __cplusplus
#include <iostream>
#endif
#define PRINT(x) ; Print ( #x, ":" , string (x))
template < typename T>
class main_wrapper{
public :
T data;
};
template < typename T>
class external_wrapper{
public :
T data;
};
template < typename T>
class A{
public :
template < typename T1>
class internal_wrapper : public external_wrapper<T1> {};
main_wrapper<internal_wrapper<T>> internal_wrapper_0;
main_wrapper<external_wrapper<T>> external_wrapper_0;
A(){
main_wrapper<internal_wrapper<T>> internal_wrapper_1;
main_wrapper<external_wrapper<T>> external_wrapper_1;
#ifdef __MQL5__
PRINT( __FUNCSIG__ );
PRINT( typename (internal_wrapper_0.data.data)); // (Bug) int int
PRINT( typename (external_wrapper_0.data.data)); // (OK) int B*
PRINT( typename (internal_wrapper_1.data.data)); // (Bug) int int
PRINT( typename (external_wrapper_1.data.data)); // (OK) int B*#endif
}
};
class B{
char data[ 10 ];
};
class C{
char data[ 1000 ];
};
voidOnStart ()
{
A< int > val_int;
A<B*> val_ptr;
printf ( "%d\n" , sizeof (main_wrapper<A<B>::internal_wrapper<B>>)); // (Bug) 36 //sizeof(main_wrapper<A<int>::internal_wrapper>) is usedprintf ( "%d\n" , sizeof (main_wrapper<A<C>::internal_wrapper<C>>)); // (Bug) 36 //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
}
감사합니다. 실제로 예제의 경우 더미 템플릿 매개변수를 도입하면 문제를 우회할 수 있습니다. 그러나 전역 프로젝트 와 관련하여 여기에서는 모든 것이 조금 더 복잡합니다. 내부 클래스 는 개발 프로세스와 최종 컨테이너 클래스 사용을 모두 단순화하기 위해 누락된 typedef typename 기능의 대안으로 사용되었습니다. 개발자의 수정을 기다릴 가치가 있을 수 있습니다. 극단적인 경우 실행 중에 정의되지 않은 동작으로 다른 성공적인 컴파일이 없기를 바라면서 모든 종속성을 끌어야 합니다.
template < typename _Tp, typename _Allocator>
class __vector_base{
public :
class allocator_type : public _Allocator{};
protected :
#define value_type _Tp
#define size_type DEFAULT_SIZE_TYPE
#define difference_type size_type
struct pointer : public allocator_type::pointer{};
struct iterator : public allocator_type::pointer{};
............................
#undef value_type
#undef size_type
#undef difference_type
};
그리고 언뜻보기에 보이는 것보다 더 많은 문제가 있습니다. #define을 typedef 선언으로 사용할 때의 문제:
- 클래스 외부에서 사용되는 데이터 유형을 전송할 수 있는 방법이 없습니다(단순 데이터 유형은 전혀 전송할 수 없음). - 대응하는 #undef 쌍인 #define의 범위를 지속적으로 제어해야 합니다.
내부 클래스를 typedef 선언으로 사용할 때의 문제:
- 사용된 데이터 클래스/구조체의 유형을 클래스 외부로 전송할 수 있습니다(단순 데이터 유형은 전혀 전송할 수 없음). - 상속할 때 모든 생성자가 손실되고 기본 클래스의 서명에 따라 수동으로 다시 작성해야 합니다. - typedef 선언이 사용된 클래스에 기본 클래스가 있는 경우 네임스페이스의 겹침을 통해 typedef 선언과 동일한 이름을 사용할 수 없습니다. - 클래스는 클래스에서 상속되고 구조는 구조에서 상속되므로 지속적으로 모니터링해야 합니다.
기본 할당 연산자의 도입으로 인해 기본 클래스에 대한 우발적인 할당을 방지할 필요가 있었습니다. 이를 위해 개발자는 "operator=delete"를 추가했습니다. 그러나 모든 것을 다시 수동으로 작성해야 하기 때문에 삭제/기본 링크를 끊는 것은 논리적이지 않은 것 같습니다. 내가 뭔가 잘못하고 있는 건 아닐까?
class Base{
char base_data[ 100 ];
};
template < typename T>
class A : public Base{
int data_1;
int data_2;
int data_3;
int data_4;
int data_5;
int data_6;
int data_7;
int data_8;
int data_9;
char arr_1[];
char arr_2[];
public :
// MQL
A* operator =(A &obj){
data_1 = obj.data_1;
data_2 = obj.data_2;
data_3 = obj.data_3;
data_4 = obj.data_4;
data_5 = obj.data_5;
data_6 = obj.data_6;
data_7 = obj.data_7;
data_8 = obj.data_8;
data_9 = obj.data_9;
ArrayCopy (arr_1, obj.arr_1);
ArrayCopy (arr_2, obj.arr_2);
(Base) this = obj;
return & this ;
};
// C++// A& operator=(A &) = default;template < typename TT>
A* operator =(A<TT> &) = delete ;
};
voidOnStart ()
{
A< int > a;
A< int > b;
A< double > c;
a = b;
//a = c;
}
혹시 휴대용 모드 키가 필요하지 않습니까?
모든 터미널에서 손이 시작되었습니까?
손, 예 모든 것이 시작되었습니다. 결과적으로 그는 손으로 그것을 발사했습니다.
휴대용 모드 키는 이와 관련하여 아무 것도 변경하지 않습니다.
사실은 MT4가 인증 창을 버리고 프로그램 실행이 완료된 것으로 간주되지 않는다는 것입니다.
배치 파일에서 "시작"을 사용해야 합니다.
일반적으로이 문제를 알아 냈습니다.
참여해주셔서 감사합니다!
당신은 여전히 문제가 무엇인지 이해하지 못하고 분명히 부주의하게 내 게시물을 읽었습니다. 여러분이 아니라 개발자에게 호소 합니다. 나는 당신의 값싼 조언이 필요하지 않습니다.
긴장을 풀고 너무 걱정하지 마십시오.
다시 한 번, 나는 대뇌 회선의 발달이 낮은 사람들이 일반적으로 공손함에 대해 거의 이해하지 못한다고 확신합니다.
당신은 지식이 많은 사람들이 당신에게 말하는 것을 이해하지도 못하지만, 당신은 아직 제대로 쓰는 법을 배우지 못한 유치원 아이처럼 무례합니다.
그러나 언어의 기능 을 평가하고 단점과 버그를 발견할 수 있게 하는 것은 프로젝트 작업입니다...
이전에는 MQL 프로젝트 작업 시 결함(버그)에 대한 정보가 발견된 순서대로 제공되었습니다.
이제 새로운 접근 방식을 시도하기로 결정했습니다. 감지된 모든 결함에 대한 정보의 후속 제공과 함께 차단 결함까지 작업했습니다.
내부 유형 "C"로 여러 번 래핑된 복잡한 객체를 생성하면 완전히 다른 데이터 유형 , 아마도 "B", 아마도 "int", 원하는 것이 무엇이든 ...
문제가 코드에 있는 것이 아니라 MQL 컴파일러의 작업에 있다는 것을 파헤치고 이해하는 데 많은 시간과 노력을 기울였습니다. (C++ 온라인: https://onlinegdb.com/H1R1fR5ML )
아마도 문제는 컴파일 타임에 코드를 생성할 때 템플릿 클래스 "main_wrapper"의 캐시에 있고 내부 클래스 "internal_wrapper"가 다양한 데이터 유형(int, B*, 나, 다).
어떤 첫 번째 데이터 유형이 템플릿 클래스 "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>에 의해 생성될 것이며, 이 데이터 유형은 향후 이 템플릿의 모든 개체에서 추가로 사용될 것입니다.
템플릿 클래스 코드 생성과 관련된 또 다른 버그는 아래에 제공됩니다.
내부 클래스를 사용할 때 템플릿 클래스 코드 생성과 관련된 또 다른 MT5(빌드 2316) 버그.
C++ 온라인: https://onlinegdb.com/HJkKXAqMU
내부 클래스 와 관련된 MT5(빌드 2316)의 또 다른 결함은 전역 네임스페이스를 명시적으로 참조할 수 없다는 것입니다.
C++ 온라인: https://onlinegdb.com/H14NF05G8
추가 개발을 차단하는 매우 불쾌한 버그.
내부 유형 "C"로 여러 번 래핑된 복잡한 객체를 생성하면 완전히 다른 데이터 유형 , 아마도 "B", 아마도 "int", 원하는 것이 무엇이든 ...
문제가 코드에 있는 것이 아니라 MQL 컴파일러의 작업에 있다는 것을 파헤치고 이해하는 데 많은 시간과 노력을 기울였습니다. (C++ 온라인: https://onlinegdb.com/H1R1fR5ML )
아마도 문제는 컴파일 타임에 코드를 생성할 때 템플릿 클래스 "main_wrapper"의 캐시에 있고 내부 클래스 "internal_wrapper"가 다양한 데이터 유형(int, B*, 나, 다).
어떤 첫 번째 데이터 유형이 템플릿 클래스 "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>에 의해 생성될 것이며, 이 데이터 유형은 향후 이 템플릿의 모든 개체에서 추가로 사용될 것입니다.
템플릿 클래스 코드 생성과 관련된 또 다른 버그는 아래에 제공됩니다.
그래서 그렇지?
감사합니다. 실제로 예제의 경우 더미 템플릿 매개변수를 도입하면 문제를 우회할 수 있습니다.
그러나 전역 프로젝트 와 관련하여 여기에서는 모든 것이 조금 더 복잡합니다. 내부 클래스 는 개발 프로세스와 최종 컨테이너 클래스 사용을 모두 단순화하기 위해 누락된 typedef typename 기능의 대안으로 사용되었습니다.
개발자의 수정을 기다릴 가치가 있을 수 있습니다.
극단적인 경우 실행 중에 정의되지 않은 동작으로 다른 성공적인 컴파일이 없기를 바라면서 모든 종속성을 끌어야 합니다.
내부 클래스 기능을 요약하자면,
정상적인 사용을 위해 typedef 선언 기능은 최소한 원시 형식은 매우 부족하다고 분명히 말할 수 있습니다.
따라서 매우 간결하고 이해하기 쉬운 C++ 코드 대신:
내부 클래스를 통해 #define 및 상속으로 울타리를 보호해야 합니다.
내부 클래스를 typedef 선언으로 사용할 때의 문제:그리고 언뜻보기에 보이는 것보다 더 많은 문제가 있습니다.
#define을 typedef 선언으로 사용할 때의 문제:
이를 위해 개발자는 "operator=delete"를 추가했습니다.
그러나 모든 것을 다시 수동으로 작성해야 하기 때문에 삭제/기본 링크를 끊는 것은 논리적이지 않은 것 같습니다.
내가 뭔가 잘못하고 있는 건 아닐까?