열거 형을 순차적으로 반복하는 방법은 무엇입니까? - 페이지 7

 
Комбинатор :

하지만 댓글에 있는 일반 이름은 어떻습니까?

동적 ENUM - 내부 사용의 경우 설정 창에 표시되지 않습니다. 일반 이름/코멘트는 실제로 필요하지 않습니다.
 

그런데 mql 전처리기에 오류가 있는 것 같습니다.

 #define i ##nt ll;

'i nt ll;'로 확장됩니다. 오류가 발생합니다.

'i nt' - undeclared identifier    t_t_t.mq4    50    1


열거형의 주석과 관련하여 - 이론상으로는 C 전처리기로 전환해야 합니다. 따라서 댓글을 밀 수 있다고 해도 효과가 거의 없었을 것입니다. 좋은 방법으로 구문(예: _cmnt_)을 변경하고 주석을 가져오는 전처리기로 C 전처리기를 호출하는 순서를 변경해야 합니다. 그러한 개혁에 대한 전망은 거의 없다고 생각합니다))

 
pavlick_ :

그런데 mql 전처리기에 오류가 있는 것 같습니다.

'i nt ll;'로 확장됩니다. 오류가 발생합니다.

어딘가에 오류가 있습니다. 정확하게 그는 다음과 같이 밝히고 있습니다. nt ll;
 
Alexander Puzanov :
동적 ENUM - 내부 사용의 경우 설정 창에 표시되지 않습니다. 일반 이름/코멘트는 실제로 필요하지 않습니다.
이러한 동적 열거형은 훨씬 더 예쁜 형태로 압축될 수 있습니다.
 

이전 방법에서는 열거형 아래에 수동으로 공백을 작성하고 값 배열을 반환하는 함수가 필요했습니다. 나는 이것을 파악하고 쓸 필요가 없어지도록 쓰기로 결정했습니다. 사실, 이것은 mql에서 컴파일할 수 없으며 가변 개수의 인수가 있는 매크로가 없지만 이론적으로는 나타날 수 있습니다. 일반적으로 다음과 같은 일이 발생했습니다.

 // Выглядит страшно, да )). Но это универсальная заготовка
// Можно засунуть в какой-нибудь cpp_magic.h
//cpp_magic.h
#define EVAL(...) EVAL1024(__VA_ARGS__)
#define EVAL1024(...) EVAL512(EVAL512(__VA_ARGS__))
#define EVAL512(...) EVAL256(EVAL256(__VA_ARGS__))
#define EVAL256(...) EVAL128(EVAL128(__VA_ARGS__))
#define EVAL128(...) EVAL64(EVAL64(__VA_ARGS__))
#define EVAL64(...) EVAL32(EVAL32(__VA_ARGS__))
#define EVAL32(...) EVAL16(EVAL16(__VA_ARGS__))
#define EVAL16(...) EVAL8(EVAL8(__VA_ARGS__))
#define EVAL8(...) EVAL4(EVAL4(__VA_ARGS__))
#define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__))
#define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__))
#define EVAL1(...) __VA_ARGS__
#define SECOND(a, b, ...) b
#define FIRST(a, ...) a
#define CAT(a,b) a ## b
#define EMPTY ()
#define DEFER1(m) m EMPTY ()
#define DEFER2(m) m EMPTY EMPTY ()()
#define DEFER3(m) m EMPTY EMPTY EMPTY ()()()
#define DEFER4(m) m EMPTY EMPTY EMPTY EMPTY ()()()()
#define IS_PROBE(...) SECOND(__VA_ARGS__, 0 )
#define PROBE() ~, 1
#define NOT(x) IS_PROBE(CAT(_NOT_, x))
#define _NOT_0 PROBE()
#define BOOL(x) NOT(NOT(x))
#define HAS_ARGS(...) BOOL(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)())
#define _END_OF_ARGUMENTS_() 0
#define IF_ELSE(condition) _IF_ELSE(BOOL(condition))
#define _IF_ELSE(condition) CAT(_IF_, condition)
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...)             _IF_0_ELSE
#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__
#define MAP1(m, first, ...)          \
  m(first)                           \
  IF_ELSE(HAS_ARGS(__VA_ARGS__))(    \
  DEFER2(_MAP1)()(m, __VA_ARGS__)    \
  )()
#define _MAP1() MAP1
#define MAP2(m, first, second, ...)  \
  m(first, second)                   \
  IF_ELSE(HAS_ARGS(__VA_ARGS__))(    \
  DEFER2(_MAP2)()(m, __VA_ARGS__)    \
  )()
#define _MAP2() MAP2
 // main.cpp
#include <stdio.h>
#include "cpp_magic.h"

#define CREATE_ENUM_HELPER_1(el, val)  el = val,
#define CREATE_ENUM_HELPER_2(el, val)  el,
#define CREATE_ENUM(name, ...)                                     \
   enum name{                                                       \
    EVAL( MAP2(CREATE_ENUM_HELPER_1, __VA_ARGS__) )                \
  };                                                               \
   unsigned get_ ##name##_array(int *ar){                            \
     int temp[] = {                                                 \
    EVAL( MAP2(CREATE_ENUM_HELPER_2, __VA_ARGS__) )                \
    };                                                             \
     if (ar != NULL )                                                 \
       for ( unsigned i = 0 ;  i < sizeof (temp) / sizeof ( int );  ++i){  \
        ar[i] = temp[i];                                           \
    }                                                              \
     return sizeof (temp) / sizeof ( int );                             \
  };

CREATE_ENUM(enum1, q, 1 , e, 3 , t, 65 , z, 90 )
CREATE_ENUM(enum2, ww, 100 , ss,- 3 , dh, 21 )
struct S{
  CREATE_ENUM(enum3, q, 871 , e, 213 , t, 226 )
}s;

int main()
{
   int ar[ 100 ];

   printf ( "----enum1-----\n" );
  get_enum1_array(ar);
   for ( unsigned i = 0 ;  i < get_enum1_array( NULL );  ++ i)
     printf ( "%d\n" , ar[i]);

   printf ( "----enum2-----\n" );
  get_enum2_array(ar);
   for ( unsigned i = 0 ;  i < get_enum2_array( NULL );  ++ i)
     printf ( "%d\n" , ar[i]);

   printf ( "----enum3-----\n" );
  s.get_enum3_array(ar);
   for ( unsigned i = 0 ;  i < s.get_enum3_array( NULL );  ++ i)
     printf ( "%d\n" , ar[i]);
}

Выхлоп printf:
 ----enum1-----
 1
 3
 65
 90
 ----enum2-----
 100
 -3
 21
 ----enum3-----
 871
 213

226

// emum1에 대해 생성된 코드
// 열거형 enum1{
// q = 1,
// 전자 = 3,
// t = 65,
// z = 90,
// };
// 서명되지 않은 get_enum1_array(int *ar){
// 정수 임시[] = { q, e, t, z, };
// if(ar != NULL)
// for(부호 없는 i = 0; i < sizeof(temp) / sizeof(int); ++i){
// ar[i] = 임시[i]; }
// 반환 sizeof(temp) / sizeof(int);
// };

이 주제에 대한 기사 http://jhnet.co.uk/articles/cpp_magic. 일반적으로 많은 마법이 물론 있습니다. 그러나 이 기술은 전처리기 코드 생성과 관련된 광범위한 작업에 유용할 수 있습니다.

C Pre-Processor Magic - Articles - Jhnet
  • jhnet.co.uk
The C Pre-Processor (CPP) is the somewhat basic macro system used by the C programming language to implement features such as and which allow very simple text-substitutions to be carried out at compile time. In this article we abuse the humble to implement if-statements and iteration. Before we begin, a disclaimer: these tricks, while perfectly...
 
주석) 하지만 존경
 

나는 관심을 가지고 스레드를 읽었습니다. 모든 것이 매크로로 매우 멋집니다.

단지 명확하지 않습니다. 열거형과 함께 이러한 춤이 왜 필요한가요? 실제적인 예를 들어주실 수 있습니까?

TF에 대해 명확하지만 또한?

 
pavlick_ :

사실, 이것은 mql에서 컴파일할 수 없으며 가변 개수의 인수가 있는 매크로가 없지만 이론적으로는 나타날 수 있습니다.

자, 이것이 핵심입니다. MQL5에서 매크로는 고정된 개수의 인수를 가질 뿐만 아니라 이 개수도 8개로 제한됩니다. 따라서 3개의 값에 대해서만 열거형을 만들 수 있습니다.

그리고 이론적으로 보면 enum 파싱을 위한 일반 함수가 더 빨리 나타날 것입니다. 개발자들은 이미 무언가를 낳겠다고 약속했습니다.

 
Alexey Navoykov :

자, 이것이 핵심입니다. MQL5에서 매크로는 고정된 수의 인수를 가질 뿐만 아니라 이 수도 8로 제한됩니다. 따라서 3개의 값에 대해서만 열거형을 만들 수 있습니다.

그리고 이론적으로 보면 enum 파싱을 위한 일반 함수가 더 빨리 나타날 것입니다. 개발자들은 이미 무언가를 낳겠다고 약속했습니다.

열거자 값을 반복하는 반복자는 계획되어 있지 않습니다.
이전에 제안된 방법을 사용하여 배열을 사용하여 값을 반복합니다.
 enum Enum
 {
  VAL_0,
  VAL_1,
  ...
 };

const Enum EnumValues[]={ VAL_0, VAL_1, ... };

for ( uint i= 0 ;i< ArraySize (EnumValues);i++)
   Print ( EnumToString (EnumValues[i]));
 
Ilyas :
열거자 값을 반복하는 반복자는 계획되어 있지 않습니다.
이전에 제안된 방법을 사용하여 배열을 사용하여 값을 반복합니다.
이것은 동일한 스위치이지만 측면에서 본 것으로 나타났습니다. 즉, 어떤 경우에도 열거 자체와 배열(스위치의 경우)의 두 가지 목록을 유지 관리해야 합니다.