Functions or Methods with the same name and inputs but different types of outputs - page 2

 
Yasingh #:
Not really as you see for using template functions like this you have to add it in input. Which is not ok for my thing.
Thanks though 🙏🏻🙏🏻🙏🏻
Two options are available:

Either use a template, pass a reference to what you want to set.

Or, also return what you are actually returning.
-> either return an object with the information, or have a reference parameter telling you what is being returned.

Further processing can now be done with a template function, or a switch statement with casting operators to circumvent compiler warnings.
 
Another approach that may be NOT what you need is pass by reference

void getData(int index, string& retval)
  {
   retval = "string";
  }

void getData(int index, int& retval)
 {
   retval = 5;
  }

Edit:
I thought about using inheritance and polymorphism to return a polymorphic object pointer, but this will not work in mql.
 

Can we overload functions on the basis of the return type of function only?

The answer is No for most programming languages. We cannot overload functions by using different return types for the functions. In other words, if there are at least two functions in the same context (e.g., the global context, class, struct or namespace) having the same data type of formal parameters and having exactly the same number of parameters (i.e., the same function signatures) then the compiler produces a compile-time error, due to failed function reolution by the compiler (ambiguity error).

The only programming language that I know of which allows function overloading on different return types (as the OP asks) is ADA. see here.

 

Can you consider to return an object wrapper, of specific derived class for each data type? Or return just a union, where only one field is filled and type is specified in a dedicated flag?

Of course, you can't use the returned entity in an expression right away - you need to unwrap the value first on the receiving end.

 
Dominik Egert #:
Two options are available:

Either use a template, pass a reference to what you want to set.

Or, also return what you are actually returning.
-> either return an object with the information, or have a reference parameter telling you what is being returned.

Further processing can now be done with a template function, or a switch statement with casting operators to circumvent compiler warnings.

A partially working solution using template functions:

template<typename T>
T getData(int index)
  {
   if(typename(T) == "string") return (T)"string";
   if(typename(T) == "int")    return (T)5;
   if(typename(T) == "double") return (T)5.0;
   //if(typename(T) == "bool")   return (T)false;
   return (T)NULL;
  }

void OnStart()
  {
   Print( getData<string>(0) );
   Print( getData<int>(0)    );
   Print( getData<double>(0) );
   //Print( getData<bool>(0)   );
  }
 
amrali #:

A partially working solution using template functions:

The whole point that he doesn't know the type of data in index 0 so no getData<string> is possible, and he still needs to assign it to a target var..

 
Amir Yacoby #:

The whole point that he doesn't know the type of data in index 0 so no getData<string> is possible, and he still needs to assign it to a target var..

So it is impossible for the compiler to figure out which overload to call. the compiler can resolve overload by its function signature (function name + type + number + order of formal parameters). The return type is not part of the function signature.

 
Yasingh #:
Sorry for the lack of info. I thought it's better to be simplified. But overall you perfectly understood what I mean.
This task seems completely impossible, due to the static nature of the language but I thought maybe there is something new out there that I could learn. 

There is no possible generic solution to this issue in MQL currently. 5 years ago, I was facing similar issue (maybe not obvious it's similar but it is related to variant type)

What you would need is a variant "type", which is hard to implement in MQL.

If you can provide an example a bit less simplified, maybe the community can help, as the best solution depends on what you are really trying to achieve.

 

Another idea for isolating the functions (getData) with the same signatures into different contexts:

template<typename T>
class GenericValue
  {
private:
   T                 m_value;
public:
                     GenericValue(void)    : m_value((T)NULL) {   }
                     GenericValue(T value) : m_value(value)   {   }

   T                 Value(void)           { return(m_value); }
   void              operator=(T value)    { m_value = value; }

   T                 getData(int index)    { return(m_value); }
  };

void OnStart()
  {
// GenericValue<int>    intVal = new GenericValue<int>(5);
// GenericValue<string> strVal = new GenericValue<string>("string");
// GenericValue<double> dblVal = new GenericValue<double>(5.0);
// GenericValue<bool>   boolVal = new GenericValue<bool>(false);

   GenericValue<int>    intVal = 5;
   GenericValue<string> strVal = "string";
   GenericValue<double> dblVal = 5.0;
   GenericValue<bool>   boolVal = false;

   Print( intVal.getData(0) );
   Print( strVal.getData(0) );
   Print( dblVal.getData(0) );
   Print( boolVal.getData(0) );
  }
 

Thank you, everyone, for your responses!

I was trying to use iCustom to dynamically load multiple indicators with varying parameters, aiming for a flexible and reusable setup. I thought maybe if I could make the idea more abstract my answer would not be as straightforward as this post. I know the reason now. However, the lack of a true variant type in MQL5 makes handling different outputs very challenging. It seems this limitation is inherent to the language.

I appreciate all the help 🙏🙏🙏

Specifying input parameters for iCustom through set file
Specifying input parameters for iCustom through set file
  • 2021.03.30
  • UgoPinna
  • www.mql5.com
Hi, I have been developing an expert advisor which contains, at some point, a call to an indicator through iCustom...