¿Cómo puedo pasar por una enumeración de forma coherente? - página 7

 
Комбинатор:

¿Qué pasa con los nombres normales que están en los comentarios?

El ENUM dinámico es de uso interno, no se muestra en la ventana de configuración. Los nombres/comentarios normales no son realmente necesarios
 

Por cierto, parece que hay un error en el preprocesador mql.

#define  i ##nt  ll;

se expande a 'i nt ll;' y da un error:

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


En cuanto a los comentarios en la enumeración - supuestamente deben ser movidos hasta el preprocesador C. Por lo tanto, incluso si fuera posible meter un comentario, sería poco probable que tuviera efecto. En el buen sentido, debería cambiar la sintaxis (a _cmnt_, por ejemplo) y cambiar la secuencia de llamada del preprocesador C con el preprocesador que tira de los comentarios. Las perspectivas de tales reformas son poco probables, creo ))

 
pavlick_:

Por cierto, parece que hay un error en el preprocesador mql.

se expande a 'i nt ll;' y da un error:

Tienes un error en alguna parte. Se expande correctamente: 'nt ll;
 
Alexander Puzanov:
El ENUM dinámico es de uso interno, la ventana de ajustes no los muestra. Los nombres/comentarios normales no son realmente necesarios
Un enum dinámico de este tipo se puede meter en una forma mucho más bonita.
 

El último método requiere escribir los espacios en blanco manualmente para el enum y la función que devuelve un array de valores. Decidí resolverlo y escribirlo de tal manera que ya no sea necesario. Sin embargo, no se puede compilar en mql, no hay macros con número variable de argumentos, pero teóricamente pueden aparecer. En fin, esto es lo que tengo:

// Выглядит страшно, да )). Но это универсальная заготовка
// Можно засунуть в какой-нибудь 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

¡// Código generado para emum1
// enum enum1{
// q = 1,
// e = 3,
// t = 65,
// z = 90,
// };
// unsigned get_enum1_array(int *ar){
// int temp[] = { q, e, t, z, };
// if(ar != NULL)
// for(unsigned i = 0; i < sizeof(temp) / sizeof(int); ++i){
// ar[i] = temp[i]; }
// return sizeof(temp) / sizeof(int);
// }

Artículo sobre este tema http://jhnet.co.uk/articles/cpp_magic. En definitiva, mucha magia, por supuesto. Pero la técnica puede ser útil para una amplia gama de tareas referidas a la generación de código de preprocesador.

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...
 
Bummer), pero te felicito.
 

He leído el hilo con interés, todo muy chulo con las macros.

No está claro, ¿por qué necesitamos todo este baile con enum? ¿Puede dar un ejemplo práctico?

Está claro lo de la TF, pero ¿qué más?

 
pavlick_:

Sin embargo no se puede compilar en mql, no hay macros con número variable de argumentos, pero teóricamente pueden aparecer.

En MQL5 las macros no sólo tienen un número fijo de argumentos, sino que su número está limitado a 8. Así que puedes hacer un enum para sólo 3 valores.

En cuanto a la apariencia teórica, probablemente será más rápido conseguir una función propia para el análisis sintáctico de enumeraciones, ya que los desarrolladores han prometido hacer algo.

 
Alexey Navoykov:

En MQL5 las macros no sólo tienen un número fijo de argumentos, sino que el número de argumentos está limitado a 8. Así que podemos hacer un enum para sólo 3 valores.

En cuanto a la apariencia teórica, probablemente sea más rápido conseguir una función propia para el análisis sintáctico de enumeraciones. Los desarrolladores ya han prometido que se les ocurrirá algo.

No está previsto ningún iterador para enumerar los valores del enum.
Utilizar el método de enumeración propuesto anteriormente mediante un array.
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:
No está previsto ningún iterador para la enumeración de valores del enumerador.
Utilice el método sugerido anteriormente de enumerar valores utilizando un array.
Resulta ser el mismo interruptor, pero de lado. Es decir, habrá que mantener dos listas en cualquier caso: el propio enumerador y el array (casos de cambio).
Razón de la queja: