我怎样才能持续地通过列举? - 页 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,
// 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);
// }

关于这个问题的文章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...
 
Bummer),但要为你点赞。
 

我饶有兴趣地阅读了这个主题,所有的宏都非常酷。

只是不清楚,为什么我们需要这些与枚举有关的舞蹈?我可以给你一个实际的例子吗?

关于TF很清楚,但还有什么?

 
pavlick_:

然而它不能在mql中编译,没有参数数量可变的宏,但理论上它们可以出现。

在MQL5中,宏不仅有固定的参数数量,而且它们的数量被限制在8个。 所以你可以做一个只有3个值的枚举。

至于理论上的外观,可能会更快地得到一个内部函数来进行枚举解析,因为开发者已经承诺会做一些事情。

 
Alexey Navoykov:

在MQL5中,宏不仅有固定的参数数量,而且它们的数量被限制在8个。 所以我们可以做一个只有3个值的枚举。

至于理论上的出现,可能更快得到一个用于枚举解析的内部函数。 开发人员已经承诺会拿出一些东西。

没有计划用迭代器来列举枚举值。
使用之前提出的使用数组进行枚举的方法。
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:
没有为枚举器的值枚举计划迭代器。
使用之前建议的使用数组来枚举数值的方法。
原来是同一个开关,但是从侧面看。也就是说,在任何情况下都需要维护两个列表:枚举器本身和数组(切换情况)。