Come si fa a passare un'enumerazione in modo coerente? - pagina 7

 
Комбинатор:

E i nomi normali che si trovano nei commenti?

Dynamic ENUM è per uso interno, non è mostrato nella finestra delle impostazioni. I nomi/commenti normali non sono realmente necessari
 

A proposito, sembra esserci un errore nel preprocessore mql.

#define  i ##nt  ll;

si espande a 'i nt ll;' e dà un errore:

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


Per quanto riguarda i commenti nell'enumerazione - in teoria, dovrebbero essere in tensione fino al preprocessore C. Quindi, anche se fosse possibile inserire un commento, sarebbe improbabile che abbia un effetto. In senso buono, dovete cambiare la sintassi (a _cmnt_, per esempio) e cambiare la sequenza di chiamata del preprocessore C con il preprocessore che tira i commenti. Le prospettive di tali riforme sono improbabili, credo ))

 
pavlick_:

A proposito, sembra esserci un errore nel preprocessore mql.

si espande a 'i nt ll;' e dà un errore:

Hai un errore da qualche parte. Si espande correttamente: 'nt ll;
 
Alexander Puzanov:
Dynamic ENUM è per uso interno, la finestra delle impostazioni non li mostra. I nomi/commenti normali non sono realmente necessari
Un tale enum dinamico può essere infilato in una forma molto più bella.
 

L'ultimo metodo richiede di scrivere manualmente gli spazi vuoti per enum e la funzione che restituisce un array di valori. Ho deciso di capirlo e di scriverlo in modo tale che non sia più necessario. Tuttavia, non può essere compilato in mql, non ci sono macro con numero variabile di argomenti, ma teoricamente possono apparire. Comunque, ecco quello che ho:

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

// Codice generato per 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);
// }

Articolo su questo argomento http://jhnet.co.uk/articles/cpp_magic. Tutto sommato, un sacco di magia, naturalmente. Ma la tecnica può essere utile per una vasta gamma di compiti relativi alla generazione di codice preprocessore.

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) ma complimenti a te.
 

Ho letto il thread con interesse, tutto molto cool con le macro.

Non è chiaro, perché abbiamo bisogno di tutto questo ballare con gli enum? Può fare un esempio pratico?

È chiaro su TF, ma cos'altro?

 
pavlick_:

Tuttavia non può essere compilato in mql, non ci sono macro con numero variabile di argomenti, ma teoricamente possono apparire.

In MQL5 le macro non solo hanno un numero fisso di argomenti, ma il loro numero è limitato a 8. Così si può fare una enum per soli 3 valori.

Per quanto riguarda l'aspetto teorico, sarà probabilmente più veloce ottenere una funzione interna per l'analisi degli enum, dato che gli sviluppatori hanno già promesso di fare qualcosa.

 
Alexey Navoykov:

In MQL5 le macro non solo hanno un numero fisso di argomenti, ma il loro numero è limitato a 8. Quindi possiamo fare una enum per soli 3 valori.

Per quanto riguarda l'aspetto teorico, è probabilmente più veloce ottenere una funzione interna per l'analisi degli enum. Gli sviluppatori hanno già promesso di fare qualcosa.

Non è previsto alcun iteratore per enumerare i valori di enum.
Utilizza il metodo di enumerazione proposto in precedenza utilizzando l'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:
Nessun iteratore è previsto per l'enumerazione dei valori.
Usate il metodo precedentemente suggerito per enumerare i valori usando un array.
Risulta essere lo stesso interruttore, ma di lato. Cioè, due liste dovranno essere mantenute in ogni caso: l'enumeratore stesso e l'array (casi di switch).