Reputation: 7232
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 ?
Upvotes: 3
Views: 4603
Reputation: 10103
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!
Upvotes: 0
Reputation: 206717
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);
Upvotes: 6
Reputation: 76396
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.
Upvotes: 2