Compiler errors 如何定义指向同名静态类方法的全局宏?

Compiler errors 如何定义指向同名静态类方法的全局宏?,compiler-errors,syntax-error,mql4,mql5,Compiler Errors,Syntax Error,Mql4,Mql5,我有以下MQL4/5代码: class MQL4 { public: static double Ask() { MqlTick _tick; SymbolInfoTick(_Symbol, _tick); return _tick.ask; // Overriding Ask variable to become a function call. #define Ask MQL4::Ask() } }; void start() { do

我有以下MQL4/5代码:

class MQL4 {
public:
  static double Ask() {
    MqlTick _tick;
    SymbolInfoTick(_Symbol, _tick);
    return _tick.ask;
    // Overriding Ask variable to become a function call.
    #define Ask MQL4::Ask()
  }

};

void start() {
  double ask = Ask; // line 14
};
但是,根据错误,它无法在MQL4或MQL5下编译:

> mql /s /mql5 Test.mqh
MQL4/MQL5 Compiler build 1162 (02 Jul 2015)
Test.mqh : information: Checking 'Test.mqh'
Test.mqh(14,16) : error 320: 'Ask' - too complex, simplify the macro
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 239: '::' - syntax error
Test.mqh(14,16) : error 149: unexpected token
Test.mqh(14,16) : error 149: ')' - unexpected token
Test.mqh(14,16) : error 157: 'MQL4' - expression expected
Test.mqh(14,10) : warning 31: variable 'ask' not used
 : information: Result 11 error(s), 1 warning(s)
与最新1498版本相同的错误

基本上是说Ask宏太复杂了。虽然将Ask方法重命名为GetAsk并更新宏定义时效果很好,但是我想了解是否有其他解决方案而不必重命名它

我是否可以定义任何语法来理解以下宏:

#define Ask MQL4::Ask()

不必重命名它,同时仍将其保留在静态类方法中?

宏替换应该在函数之外的某个位置声明。尝试将define Ask MQL4::Ask移到类声明上方或程序的第一行

UPD。对话结束后,宏应该有不同的名称

#define method (Class::method()) //doesnt work, 
#define method (Class::Method()) //or (Class::method_()) is fine
是的,但是…,不!定义替换很好,但是。。。但是Ask是一个保留字,这会使编译器感到困惑。 问题实际上是编译器预处理器的能力有限,而不是.method的同名

define指令(包括非参数和参数)的替换功能在已发布的MQL4/5语言语法的限制下进行了测试

案例[6]最终证明, 这个班。可以具有相同的名称。Ask,但不能与define-s相同

后记: 正如我所发布的,在对基于define指令的预编译器替换(用于版本管理)等的功能进行了广泛测试后,我只能得出一个结论,即尽量避免使用此功能,因为由此产生的问题比令人惊讶的字符串处理限制要昂贵得多,关于持续的语言爬行的不确定性,下一个构建版本后语法糖把戏的不可预测的结果等,都不利于预期目的


它不会有任何区别,因为编译器不会在函数中看到它。为了方便起见,它只是放在Ask方法定义之后。看:您的代码和输出-将宏移开并放入宏中,顺序并不重要,但在您的代码中,您已经将Ask重命名为Ask,那么它就可以正常工作了。但我希望将点Ask宏显式地放入MQL4::Ask。使用带大写字母的ASK不是MQL4中的标准,因为在MQL5下运行的现有MQL4代码将使用该类,该类将使用ASK,而不是ASK。因此,改变名字的方法是我想要避免的一种方法。如果将函数重命名为ask-它可以工作。也许它不想让宏和函数名相等,也就是说,如果不重命名变量或方法,这是不可能的?“Ask是一个保留字,这会混淆编译器”这是不正确的,如果在整个代码中将Ask更改为Foo,编译器将显示关于太复杂宏的相同错误,所以这不是一个保留字。在这种情况下[id]?嗯,没有人可以重命名硬编码系统。接下来,最薄弱的一点是define-pre-compiler替换,它依次替换每个的所有外观,之后lexer通常会死机。抱歉,这超出了MQL4/5端代码设计的控制范围。您的第一句话是“Ask是一个保留字,这会混淆编译器”。MQL5中的Ask变量不存在,同样的情况也存在,因此它与保留字无关。我认为主要的问题是宏定义的值中有宏名称,所以每个Ask都会被它的值替换,然后重复替换后会发生同样的情况,直到编译器意识到它太复杂时,进行了几次迭代。如果取消注释并重新测试不同的[Case[id]-s,错误消息会有所不同,根据冲突开始的位置不同,但通常会显示预编译器替换的发散恐慌与lexer恐慌相结合,因为中间表示的复杂性不断增加,它无法在代码结构分析中令人满意地终止,并在大约30个嵌套级别后在恐慌状态中出现。
//+------------------------------------------------------------------+
//|                                   StackOverflow__test_DEFINE.mq4 |
//|                                       Copyright © 1987-2017 [ME] |
//|                                                       nowhere.no |
//+------------------------------------------------------------------+
#property strict
 // -------------------------------------------------------------------------------------------------------------------------
/*                                                       // [Case[1] FAILS BELOW
#define               Ask MQL4::Ask( True )              // [Case[1] // Overriding Ask variable to become a function call. */

class MQL4 { 
     public:
     static double Ask( bool FakeSyntaxSUGAR = False ) { // [Case[1] FAILS HERE TO PROCESS EXPANDED PRE-PROCESSOR #define SUBSTITUTION]
                        MqlTick _tick;
                        SymbolInfoTick( _Symbol,
                                        _tick
                                        );
                        return _tick.ask;
         }
};

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+

void OnStart() {

 // -------------------------------------------------------------------------------------------------------------------------
/*                                                       // [Case[2] FAILS
#define               Ask MQL4::Ask( True )              // [Case[2] // Overriding Ask variable to become a function call. */
  // double ask     = Ask;                               // [Case[2] FAILS TO COMPILE, ERROR on "Ask;"]


  // ------------------------------------------------------------------------------------------------------------------------
  // double askMQL4 = MQL4::Ask( True );                 // [Case[3] OK    TO COMPILE EXPLICIT CALL TO an explicit absolute reference to a method-name]


 // -------------------------------------------------------------------------------------------------------------------------
/*                                                       // [Case[4] OK */
     MQL4* aPtrToINSTANCE = new MQL4();                  // [Case[4]
  // double askINST = aPtrToINSTANCE.Ask( False );       // [Case[4] OK    TO COMPILE EXPLICIT CALL TO aPtrToINSTANCE-referred instance of Class ]

 // -------------------------------------------------------------------------------------------------------------------------
/*                                                       // [Case[5] FAILS
#define               Ask aPtrToINSTANCE.Ask( False )    // [Case[5] */
  // double askINST = Ask;                               // [Case[5] FAILS TO PRE-PROCESS #define HERE ]


 // -------------------------------------------------------------------------------------------------------------------------
/*                                                       // [Case[6] OK */
#define               Ask_with_SomeOtherDEFINE_NAME aPtrToINSTANCE.Ask( False )
     double askINST = Ask_with_SomeOtherDEFINE_NAME;     // [Case[6] OK    TO CALL THE .Ask() METHOD AS THE PRE-PROCESSOR <_SYMBOL_TO_SUBSTITE_> WAS #define-d AS NON-COLLIDING]

//    **   *   ****        ****        *****        *****
//    ***  *  **   *      **   *       **           **   *
//    ** * *  **   *      **   *       ***          **    *
//    **  **  **   *      ** * *       **           **   * 
//    **   *   ****  **    ****   **   *****  **    *****  **
//                   *         *  
}; 
// ------------------------------------------------------------------