2
votes

I know we are not allowed to overload functions based on return type only. Suppose I have two functions double convert(string num) and int convert(string num) Consider the following sample code :

double convert(string num){
    stringstream ss;
    double d_num;
    ss<<num;
    ss>>d_num;
    return d_num;
}

int convert(string num){
    int i_num;
    /*.....
   same as previous
   .....
   */
   return i_num;
}

And in the main() :

int main(){
    string st="09122321";
    double d1=convert(st);
    int i1=convert(st);

}

Although I overloaded the function differring only in return type but as I am assigning them to data types based on their return type wasn't I supposed to get the converted string num in double d1 and int i1 ?

Now I get the error similar to:

error: new declaration 'int convert(std::string)'| error: ambiguates old declaration 'double convert(std::string)'|

How will I make the convert() work if I want it to have it different return types by overloading the function ?

3
Just rename it. Have to_int(std::string) and to_float(std::string).fuzzything44
There's an old trick to say struct convert { convert(string); operator double(); operator int(); };Johannes Schaub - litb
FYI STL has already functions for these conversions namely std::stoi and std::stod101010

3 Answers

6
votes

How will I make the convert() work if I want it to have it different return types by overloading the function ?

You can create a simple function template.

template <typename T>
T convert(std::string const& num){
    std::istringstream ss(num);
    T d_num;
    ss>>d_num;
    return d_num;
}

and specialize it for std::string so that the input argument is used to copy construct the returned std::string.

template <>
std::string convert<std::string>(std::string const& in){
    return in;
}

and use it as:

auto d1 = convert<double>(st);
auto i1 = convert<int>(st);
2
votes

One way would be to pass the required return type as an output variable. With this, your code would become:

void convert(string num, double *d_num){
    stringstream ss;
    ss<<num;
    ss>>*d_num;
}

void convert(string num, int *i_num){
    /*.....
   same as previous
   .....
   */
}

Since the functions differ in their argument-signature, the overload is fine.

0
votes

You cannot overload based upon return type in C and C++, but you can cheat by returning a class and providing conversion operators. (And don't forget an insertion operator.) Behold:

#include <iostream>
#include <string>

struct fib
{
  unsigned long value;

  fib( unsigned n )
  {
    value = !!n;
    if (!n) return;
    unsigned long prev = 0;
    while (--n)
    {
      long next = value + prev;
      prev = value;
      value = next;
    }
  }

  operator long () const { return value; }
  operator std::string () const { return std::to_string( value ); }
};

std::ostream& operator << ( std::ostream& outs, const fib& f )
{
  return outs << (std::string)f;
}

void print( double x )
{
  std::cout << "fib 3 = " << x << "\n";
}

int main()
{
  long        x = fib( 5 );
  std::string s = fib( 7 );

  print( fib( 3 ) );
  std::cout << "fib 5 = " << x << "\n";
  std::cout << "fib 7 = " << s << "\n";
  std::cout << "fib 9 = " << fib( 9 ) << "\n";
}

Enjoy!