How to judge variable types ?

 
template<typename T>
void Test(T input)
 {
  if(T is double)
    ...
  if(T is int)
   ...
 }

I hope to perform different treatment by judging variable types in a function. Does MQL5 can do it?

 
Yu Zhang:

I hope to perform different treatment by judging variable types in a function. Does MQL5 can do it?

Yes, but not like you have shown.

You need a function signature for every type, like this:


void Test(double input)
void Test(int input)
void Test(datetime input)

For the case of enums, you can use a template.

I have used this heavily in my code base project MQLplus Debugging Library.

Take a look at file: lib_debug_type_to_string.mqh

 

Simply use typename as a function directly:

template<typename T>
void Test(T a)
 {
  if(typename(T)=="double")
  {
   printf("double");
  }

  if(typename(T)=="int") 
  {
   printf("int");
  }
 }
 
Ziheng Zhuang #:

Simply use typename as a function directly:

you cannot build code processing different data types by selecting the type based on typename. It will not compile.

Show me an example that compiles beyond what you have shown. You will see, it's not possible.
 
Ziheng Zhuang #:

Simply use typename as a function directly:

Thank you.

 
Dominik Christian Egert #:
you cannot build code processing different data types by selecting the type based on typename. It will not compile.

Show me an example that compiles beyond what you have shown. You will see, it's not possible.

Sure you can, of course not to build complex generic code, but it's useful.

   template<typename Т>
   uint              Write(const Т value,int length=-1)
     {
      string typeх = typename(Т);

      if(typeх=="double")
         return(FileWriteDouble(handleф,(double)value));

      if(typeх=="long" || typeх=="ulong" || typeх=="datetime")
         return(FileWriteLong(handleф,(long)value));

      if(typeх=="float")
         return(FileWriteFloat(handleф,(float)value));

      if(typeх=="string")
         return(FileWriteString(handleф,(string)value,length));

      //--- remains all integer types
      return(FileWriteInteger(handleф,(int)value,sizeof(Т)));
     }
EDIT: Source code updated to fix the warnings. Thanks to Dominik.
 
Dominik Christian Egert #:
you cannot build code processing different data types by selecting the type based on typename. It will not compile.

Show me an example that compiles beyond what you have shown. You will see, it's not possible.

Yes, you're right, my codes only works for basic types.

Your library is too complex to understand for me. I will take time to study it. 

Thanks.

 
Alain Verleyen #:

Sure you can, of course not to build complex generic code, but it's useful.

Right.

Main difference is, templates are resolved at compile time, while typename is resolved at runtime, and it's a string comparison. 

And you are required to do a cast of the input value.

Try this with an enum, using EnumToString and it is already outside of compile compatibility.

 
Dominik Christian Egert #:
Right.

Main difference is, templates are resolved at compile time, while typename is resolved at runtime, and it's a string comparison. 

And you are required to do a cast of the input value.

Try this with an enum, using EnumToString and it is already outside of compile compatibility.

I know, but it's working, simple and efficient enough most of the time when applicable.
 
Dominik Christian Egert #:
Right.

Main difference is, templates are resolved at compile time, while typename is resolved at runtime, and it's a string comparison. 

And you are required to do a cast of the input value.

Try this with an enum, using EnumToString and it is already outside of compile compatibility.

Got some inputs from a MQ dev. typename(T) is not a function, so provided we do these changes :

   template<typename Т>
   uint              Write(const Т value,int length=-1)
     {
      if(typename(Т)=="double")
         return(FileWriteDouble(handleф,(double)value));

      if(typename(Т)=="long" || typename(Т)=="ulong" || typename(Т)=="datetime")
         return(FileWriteLong(handleф,(long)value));

      if(typename(Т)=="float")
         return(FileWriteFloat(handleф,(float)value));

      if(typename(Т)=="string")
         return(FileWriteString(handleф,(string)value,length));

      //--- remains all integer types
      return(FileWriteInteger(handleф,(int)value,sizeof(Т)));
     }

The compiler will optimize it. So the above is equivalent to :

   template<typename Т>
   uint              Write(const Т value,int length=-1)
     {
      return(FileWrite<Т>(handleф,(Т)value));          // Not possible in MQL, just to explain the workaround.
     }
 
Alain Verleyen #:

Got some inputs from a MQ dev. typename(T) is not a function, so provided we do these changes :

The compiler will optimize it. So the above is equivalent to :


That is efficient.... Very interesting, thank you for the research.
Reason: