Is it possible to overload with return values?

S

skishorev

Hi,
Here I am taking two functions. void f(int,int) and another one is
float f(int,int).
Is it possible to overload with return values.

Thx,
kishore
 
G

Guest

Hi,
Here I am taking two functions. void f(int,int) and another one is
float f(int,int).
Is it possible to overload with return values.

No.
C++ Standard (Working Draft, 2005-10-19) says:

13.1 Overloadable declarations
2 Certain function declarations cannot be overloaded:
— Function declarations that differ only in the return type cannot
be overloaded.


Cheers
 
S

Sunil Varma

No, it's not possible to overload functions based on its return type.

Ex:

void f(int);
int f(int);
main()
{
f(); // How does the compiler know to call which function in
this case.
}
 
L

Luke Meyers

Sunil said:
No, it's not possible to overload functions based on its return type.

There is one thing permitted by the language which resembles this --
covariant return types. It has more to do with overriding, though. In
the case where a parent's member function is overridden, a "more
specifically derived" (to coin a phrase?) return type -- that is, a
child of the original return type -- can be specified. To illustrate:

struct A {};
struct B : A {};
struct C { A frobnicate(); };
struct D : C { B frobnicate(); };

Note that you can also have the case where the return types are the
classes themselves, e.g.:

class A { A frob(); };
class B : A { B frob(); };

But apart from this, forget about it.

Luke
 
G

Gilles Rochefort

Hi,
Here I am taking two functions. void f(int,int) and another one is
float f(int,int).
Is it possible to overload with return values.

Thx,
kishore

C++ do not allow to overload with return values .. But, there is a trick
which consist to return an object which will invoke the appropriate
function via a type conversion operator.

Just consider the following code as an example...

Gilles Rochefort

#include <iostream>

float foo1(int x,int y)
{
return (float)x/(float)y;
}

int foo2(int x,int y)
{
return (x*y);
}


class resultFoo
{
private:
int _x,_y;

public:
resultFoo(int x,int y):_x(x),_y(y)
{}

operator float()
{ return foo1(_x,_y); }


operator int()
{ return foo2(_x,_y); }

};

resultFoo foo(int x,int y)
{
return resultFoo(x,y);
}

int main(void)
{
float a;
int b;
a = foo(3,4);
b = foo(3,4);
std::cout << "foo(3,4) = " << a << std::endl;
std::cout << "foo(3,4) = " << b << std::endl;

}
 
B

Bob Hairgrove

There is one thing permitted by the language which resembles this --
covariant return types. It has more to do with overriding, though. In
the case where a parent's member function is overridden, a "more
specifically derived" (to coin a phrase?) return type -- that is, a
child of the original return type -- can be specified. To illustrate:

struct A {};
struct B : A {};
struct C { A frobnicate(); };
struct D : C { B frobnicate(); };

Note that you can also have the case where the return types are the
classes themselves, e.g.:

class A { A frob(); };
class B : A { B frob(); };

This won't work unless you are returning pointers or references. Even
if it did, you'd have a major problem WRT slicing.
 
M

mlimber

Gilles said:
C++ do not allow to overload with return values .. But, there is a trick
which consist to return an object which will invoke the appropriate
function via a type conversion operator.

Just consider the following code as an example...

Gilles Rochefort

#include <iostream>

float foo1(int x,int y)
{
return (float)x/(float)y;
}

int foo2(int x,int y)
{
return (x*y);
}


class resultFoo
{
private:
int _x,_y;

public:
resultFoo(int x,int y):_x(x),_y(y)
{}

operator float()
{ return foo1(_x,_y); }


operator int()
{ return foo2(_x,_y); }

};

resultFoo foo(int x,int y)
{
return resultFoo(x,y);
}

int main(void)
{
float a;
int b;
a = foo(3,4);
b = foo(3,4);
std::cout << "foo(3,4) = " << a << std::endl;
std::cout << "foo(3,4) = " << b << std::endl;

}

Another method is to translate the problem into standard overloading by
passing a dummy parameter. Rather than passing a real object, however,
you can use a trick from _Modern C++ Design_ by creating an object that
contains *only* type information and that can easily be optimized away
by the compiler:

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type() {}
};

void foo( int i, Type2Type<void> ) { /*...*/ }
int foo( int i, Type2Type<int> ) { /*...*/ return i; }

void bar()
{
foo( 42, Type2Type<void>() );
foo( 42, Type2Type<int>() );
}

This trick is also useful for getting around some template problems on
non-conformant compilers (e.g. VC++ 6).

Cheers! --M
 
P

puzzlecracker

mlimber said:
Another method is to translate the problem into standard overloading by
passing a dummy parameter. Rather than passing a real object, however,
you can use a trick from _Modern C++ Design_ by creating an object that
contains *only* type information and that can easily be optimized away
by the compiler:

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type() {}
};

void foo( int i, Type2Type<void> ) { /*...*/ }
int foo( int i, Type2Type<int> ) { /*...*/ return i; }

void bar()
{
foo( 42, Type2Type<void>() );
foo( 42, Type2Type<int>() );
}

This trick is also useful for getting around some template problems on
non-conformant compilers (e.g. VC++ 6).

Cheers! --M


Gilles Rochefort trick is better and express cleanly what you want to
do; above one is a mess; any more suggestions on getting nonstandard
overloading to work?
 
M

mlimber

puzzlecracker said:
Gilles Rochefort trick is better and express cleanly what you want to
do; above one is a mess;
[snip]

"Better" is a function of need, and the OP's code may be greatly
simplified from the actual code. In any case, the Type2Type trick is
useful in templatized code like this (drawn from section 9.2 of _Modern
C++ Design_):

template <class T>
class AbstractFactoryUnit
{
virtual T* DoCreate( Type2Type<T> ) = 0;
virtual ~AbstractFactoryUnit() {}
};

In the AbstractFactory class presented in the book, there can be
multiple DoCreate overloads within the same class hierarchy, and the
Type2Type trick is used to disambiguate them. The other trick above
could not do so.

Cheers! --M
 
M

mlimber

puzzlecracker said:
mlimber said:
Another method is to translate the problem into standard overloading by
passing a dummy parameter. Rather than passing a real object, however,
you can use a trick from _Modern C++ Design_ by creating an object that
contains *only* type information and that can easily be optimized away
by the compiler:

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type() {}
};

void foo( int i, Type2Type<void> ) { /*...*/ }
int foo( int i, Type2Type<int> ) { /*...*/ return i; }

void bar()
{
foo( 42, Type2Type<void>() );
foo( 42, Type2Type<int>() );
}

This trick is also useful for getting around some template problems on
non-conformant compilers (e.g. VC++ 6).

Cheers! --M
[snip]
any more suggestions on getting nonstandard
overloading to work?

You could use template specialization (but not on VC6):

template <class T> T Foo();

template<> int Foo()
{
return 42;
}

template<> double Foo()
{
return 42.0;
}

int main()
{
const double d = Foo<double>();
return Foo<int>();
}

Cheers! --M
 
G

g

yes!
why to create dummy classes at your own for the returns????
there is tuple for this;-)!
g.
 
M

mlimber

g said:

Yes what?
why to create dummy classes at your own for the returns????
there is tuple for this;-)!

First, I did not create a dummy class at all (unless you mean in my
first response about Loki::Type2Type, in which case you responded to
the wrong post and didn't quote enough -- let me rephrase that -- ANY
context to clarify your meaning).

Second, please demonstrate your solution with a snippet of code.

Cheers! --M
 
L

Luke Meyers

Bob said:
This won't work unless you are returning pointers or references. Even
if it did, you'd have a major problem WRT slicing.

Gah, of course you're right. It's a good thing we've got compilers to
tell us these things, too. :)

Luke
 
P

puzzlecracker

mlimber said:
puzzlecracker said:
mlimber said:
Gilles Rochefort wrote:
On Thu, 29 Dec 2005 01:30:35 -0800, skishorev wrote:

Hi,
Here I am taking two functions. void f(int,int) and another one is
float f(int,int).
Is it possible to overload with return values.

Thx,
kishore

C++ do not allow to overload with return values .. But, there is a trick
which consist to return an object which will invoke the appropriate
function via a type conversion operator.

Just consider the following code as an example...

Gilles Rochefort
#include <iostream>

float foo1(int x,int y)
{
return (float)x/(float)y;
}

int foo2(int x,int y)
{
return (x*y);
}


class resultFoo
{
private:
int _x,_y;

public:
resultFoo(int x,int y):_x(x),_y(y)
{}

operator float()
{ return foo1(_x,_y); }


operator int()
{ return foo2(_x,_y); }

};

resultFoo foo(int x,int y)
{
return resultFoo(x,y);
}

int main(void)
{
float a;
int b;
a = foo(3,4);
b = foo(3,4);
std::cout << "foo(3,4) = " << a << std::endl;
std::cout << "foo(3,4) = " << b << std::endl;

}

Another method is to translate the problem into standard overloading by
passing a dummy parameter. Rather than passing a real object, however,
you can use a trick from _Modern C++ Design_ by creating an object that
contains *only* type information and that can easily be optimized away
by the compiler:

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type() {}
};

void foo( int i, Type2Type<void> ) { /*...*/ }
int foo( int i, Type2Type<int> ) { /*...*/ return i; }

void bar()
{
foo( 42, Type2Type<void>() );
foo( 42, Type2Type<int>() );
}

This trick is also useful for getting around some template problems on
non-conformant compilers (e.g. VC++ 6).

Cheers! --M
[snip]
any more suggestions on getting nonstandard
overloading to work?

You could use template specialization (but not on VC6):

template <class T> T Foo();

template<> int Foo()
{
return 42;
}

template<> double Foo()
{
return 42.0;
}

int main()
{
const double d = Foo<double>();
return Foo<int>();
}

Cheers! --M


you can NOT have functions that use template specializations:
according to the standard, only member functions and types can be
specialized.
 
G

g

Ο/Η mlimber έγÏαψε:
Yes what?


First, I did not create a dummy class at all (unless you mean in my
first response about Loki::Type2Type, in which case you responded to
the wrong post and didn't quote enough -- let me rephrase that -- ANY
context to clarify your meaning).

Second, please demonstrate your solution with a snippet of code.
when you want to be able to return from a function multiple values,if
there is a condition and if it is true to return an int else return
something else then instead of overloading & etc
use tuples
go at boost site and search for tuples!
 
M

mlimber

g said:
Ο/Η mlimber έγÏαψε:
when you want to be able to return from a function multiple values,if
there is a condition and if it is true to return an int else return
something else then instead of overloading & etc
use tuples
go at boost site and search for tuples!

But the question was how to overload for multiple types, not multiple
values. For this purpose, boost::any or boost::variant might help, but
boost::tuple seems to be misapplied here.

Cheers! --M
 
M

mlimber

puzzlecracker said:
mlimber said:
puzzlecracker said:
mlimber wrote:
Gilles Rochefort wrote:
On Thu, 29 Dec 2005 01:30:35 -0800, skishorev wrote:

Hi,
Here I am taking two functions. void f(int,int) and another one is
float f(int,int).
Is it possible to overload with return values.

Thx,
kishore

C++ do not allow to overload with return values .. But, there is a trick
which consist to return an object which will invoke the appropriate
function via a type conversion operator.

Just consider the following code as an example...

Gilles Rochefort


#include <iostream>

float foo1(int x,int y)
{
return (float)x/(float)y;
}

int foo2(int x,int y)
{
return (x*y);
}


class resultFoo
{
private:
int _x,_y;

public:
resultFoo(int x,int y):_x(x),_y(y)
{}

operator float()
{ return foo1(_x,_y); }


operator int()
{ return foo2(_x,_y); }

};

resultFoo foo(int x,int y)
{
return resultFoo(x,y);
}

int main(void)
{
float a;
int b;
a = foo(3,4);
b = foo(3,4);
std::cout << "foo(3,4) = " << a << std::endl;
std::cout << "foo(3,4) = " << b << std::endl;

}

Another method is to translate the problem into standard overloading by
passing a dummy parameter. Rather than passing a real object, however,
you can use a trick from _Modern C++ Design_ by creating an object that
contains *only* type information and that can easily be optimized away
by the compiler:

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type() {}
};

void foo( int i, Type2Type<void> ) { /*...*/ }
int foo( int i, Type2Type<int> ) { /*...*/ return i; }

void bar()
{
foo( 42, Type2Type<void>() );
foo( 42, Type2Type<int>() );
}

This trick is also useful for getting around some template problems on
non-conformant compilers (e.g. VC++ 6).

Cheers! --M

[snip]
any more suggestions on getting nonstandard
overloading to work?

You could use template specialization (but not on VC6):

template <class T> T Foo();

template<> int Foo()
{
return 42;
}

template<> double Foo()
{
return 42.0;
}

int main()
{
const double d = Foo<double>();
return Foo<int>();
}

Cheers! --M


you can NOT have functions that use template specializations:
according to the standard, only member functions and types can be
specialized.

Not only that, but the template arg MUST be used in the function
argument list (not just the return type). What sort of bonehead would
make such a foolish suggestion?! (In my defense, that snippet of code
compiled fine with Comeau. :) )

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top