Features of the mql5 language, subtleties and tricks - page 111

 
pavlick_:

...

Please use the built-in text formatting - there is a menu above the message input field - everything is there. And hotkeys are described there too.

I've fixed your "quote".

 
pavlick_:

How is it the same? There's an automatic copy constructor and all manipulation will have a view:

... 
ar.Add(new(q));


As I understand it, I meant new Q(q). Now it's clear that we were talking about the absence of automatic copy constructor in MQL.

 
Problem

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

fxsaber, 2018.12.21 10:23

I can't figure it out, please ask for a hint. There is such a time acquisition

int GetHandle() { return(0); }

bool SelectHandle( int ) { return(true); }
  
int NewHandle = 0;  
int PrevHandle = GetHandle();    

datetime time = SelectHandle(NewHandle) ? TimeCurrent() : 0;  
SelectHandle(PrevHandle);


How to write a macro that does the same thing

time = MACROS(NewHandle, TimeCurrent()); // Макрос


The problem is that PrevHandle in the macro cannot be created.

Forum on trading, automated trading systems & strategy testing

Bugs, bugs, questions

fxsaber, 2018.12.21 22:15

Let me clarify that NewHandle - can be a constant. I.e. a valid call like this
time = MACROS(0, TimeCurrent()); // TimeCurrent из 0-хендла.
time = MACROS(1, TimeCurrent()); // TimeCurrent из 1-хендла.

MACROS(0, SymbolInfoTick(_Symbol, Tick)); // SymbolInfoTick из 0-хендла.

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
Price = MACROS(3, Bid); // Bid из 3-хендла.


Solution

template <typename T>
T Memory( const T NewValue, const bool SetFlag = true )
{
  static T PrevValue;
  
  if (SetFlag)
    PrevValue = NewValue;
 
  return(PrevValue); 
}

template <typename T1, typename T2>
T2 MacrosFunc( const T1, const T2 Value, const T1 )
{
  return(Value);
}

#define  MACROS(A, B) MacrosFunc(SelectHandle(Memory(A, false)), B, SelectHandle(Memory(A)))


 
fxsaber:

Solution

...
template <typename T1, typename T2>
T2 MacrosFunc( const T1, const T2 Value, const T1 )
{
  return(Value);
}

#define  MACROS(A, B) MacrosFunc(SelectHandle(Memory(A, false)), B, SelectHandle(Memory(A)))


You will always have expression B calculated and returned, regardless of the rest.

 
Alexey Navoykov:

Your B expression will always be calculated and returned, regardless of the rest.

There's a sequential (right-to-left) calculation of the input parameters of the auxiliary functions.

 
fxsaber:

There is a sequential (right-to-left) calculation of the input parameters of the auxiliary functions.

What does this change? The macro always returns the value B
 
Alexey Navoykov:
What does this change? The macro always returns B

Try to refute the decision. I don't see any error.


First it switches to NewHandle, then it takes B, then it switches to the previous handle.

 
fxsaber:

First it switches to NewHandle, then it takes B, then it switches to the previous handle.

And the original task was like this:

SelectHandle(NewHandle) ? TimeCurrent() : 0; SelectHandle(PrevHandle);

I.e. the condition must be fulfilled
 
Alexey Navoykov:

And the original problem was this:

This is the same.

template <typename T1, typename T2>
T2 MacrosFunc( const T1 NewHandle, const T2 Value )
{
  return(Value);
}

#define  MACROS(A, B) MacrosFunc(SelectHandle(Memory(A, false)), SelectHandle(Memory(A)) ? B : 0)


After giving a comment, which summarised the problem somewhat - SymbolInfoTick and SymbolInfoDouble, etc.

 

By the way, I came to the conclusion that in the general case, if the return value type of the function is absolutely any type, then the problem is not solvable by MQL means. A decltype is required, which is not present here.

Reason: