C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

overloading on return value
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
unspammable@gmail.com
Guest





PostPosted: Mon Jun 27, 2005 10:48 am    Post subject: overloading on return value Reply with quote



A Java guy asked me, basically, how to overload a function on the type
of return value. In Java, he said, you just return Object and then cast
it to whatever you want (String, Integer)...

I explained that in C++ you can't overload on return value, but you can
do this:

string& foo(string& ret) {
...
return ret;
}

int& foo(int& ret) {
...
return ret;
}

This of course means you have to declare some variable to hold the
return value prior to calling the function.
But is there a more elegant way? I'm not interested in variants and
such. I'm just looking for something that resembles overloading on
return value, with an aesthetically pleasing syntax.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Razvan Cojocaru
Guest





PostPosted: Mon Jun 27, 2005 12:56 pm    Post subject: Re: overloading on return value Reply with quote



Quote:
A Java guy asked me, basically, how to overload a function on the type
of return value. In Java, he said, you just return Object and then cast
it to whatever you want (String, Integer)...

I explained that in C++ you can't overload on return value, but you can

Technically, you can't do it in Java either. Who's to stop you from
creating a C++ Object class and derive whatever you need you to return
from Object?


Quote:
But is there a more elegant way? I'm not interested in variants and
such. I'm just looking for something that resembles overloading on
return value, with an aesthetically pleasing syntax.

I don't know what overloading on return value looks like because I've
never seen it in either C++ or Java. Python can assign anything to a
variable, for example, but that's hadly 'overloading on return value'.


--
Razvan Cojocaru
KeyID: 1024D/04CA34DE

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
pinto
Guest





PostPosted: Mon Jun 27, 2005 12:58 pm    Post subject: Re: overloading on return value Reply with quote



u can not overload C functions on return type

although u do not like varients

u can write a varient class
with type cast operators for all the type u want, u can use it without
event knowning a varient class exist.

class Value
{
public:
void operator=(int _iValue);
void operator=(double _dValue);
//etc


void operator int();
void operator double();
//etc

private:
int i_Type;
void *p_Data;
}

when using

Value& foo()
{
return ret;
}

int i=foo();
double d=foo();


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Peter C. Chapin
Guest





PostPosted: Mon Jun 27, 2005 12:59 pm    Post subject: Re: overloading on return value Reply with quote

"unspammable (AT) gmail (DOT) com" <unspammable (AT) gmail (DOT) com> wrote in
news:1119824920.954966.200720 (AT) f14g2000cwb (DOT) googlegroups.com:

Quote:
A Java guy asked me, basically, how to overload a function on the type
of return value. In Java, he said, you just return Object and then
cast it to whatever you want (String, Integer)...

This isn't overloading on return type---at least not in the sense of
"overloading" as used by the C++ community. In the example above there
is only one function and that function does not know the context of the
call and thus can't act differently depending on how the return type is
used. Overloading on return type would look like

int f();
float f(); // Two different functions.

int x;
float y;

x = f();
y = f(); // This f is totally different than the first f.

C++ doesn't support this and, as far as I know, neither does Java.
However, Ada does allow overloading on return type.

As an aside, overloading on return type is pretty much the same, I
think, as allowing overloaded data object declarations. For example

int x;
float x; // Let's allow this.
int y = x; // Resolve 'x' to the integer version of x (exact match).

The logic for deciding which object 'x' refers to would be pretty much
the same as the logic for deciding which function to call. There may be
other issues, though. I don't believe Ada allows overloaded data objects
but it does allow parameterless functions to be overloaded on return
type and thus you can generate an example a lot like the one above.

function X return Integer;
function X return Float;
Y : Integer := X; -- Call X returning Integer.

The issue of overloading on return type in C++ has been discussed here
before and I believe the general conclusion was that it would be
possible to specify it, but that the rules would be extremely
complicated (due to interactions with other C++ features like implicit
type conversions, etc) and it wouldn't be worth the effort. Note that in
Ada the feature works better because Ada's type system is much stricter
than C++'s type system and so the rules governing overloading on return
type are much more tractable.

If you want to try simulating the feature in C++ see what you can do
with user defined type conversion operators. A class that provides an
operator int and an operator float, or something similar, might give you
the effect you are looking for.

Peter

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Motti Lanzkron
Guest





PostPosted: Mon Jun 27, 2005 1:00 pm    Post subject: Re: overloading on return value Reply with quote

On 27 Jun 2005 06:48:11 -0400, "unspammable (AT) gmail (DOT) com"
<unspammable (AT) gmail (DOT) com> wrote:

Quote:
A Java guy asked me, basically, how to overload a function on the type
of return value. In Java, he said, you just return Object and then cast
it to whatever you want (String, Integer)...

I explained that in C++ you can't overload on return value, but you can
do this:

You can overload cast operators on the "return" value.

class int_or_string {
int i;
std::string s;
public:
int_or_string(int ii, const std::string ss) : i(ii), s(ss) { }
operator int() const { return i; }
operator std::string() const { return s; }
};

int_or_string foo()
{
return int_or_string(42, "life the universe & everything");
}

int i = foo();
std::string s = foo();

This is a degenerate case of course, the returned class can be
constructed with functors and only compute the needed value.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Jonathan Bartlett
Guest





PostPosted: Mon Jun 27, 2005 4:28 pm    Post subject: Re: overloading on return value Reply with quote

Quote:
Technically, you can't do it in Java either. Who's to stop you from
creating a C++ Object class and derive whatever you need you to return
from Object?

Unfortunately, this would not work with existing classes and libraries.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Dietmar Kuehl
Guest





PostPosted: Mon Jun 27, 2005 4:59 pm    Post subject: Re: overloading on return value Reply with quote

[email]unspammable (AT) gmail (DOT) com[/email] wrote:
Quote:
I explained that in C++ you can't overload on return value, but you can
do this:

string& foo(string& ret) {
...
return ret;
}

int& foo(int& ret) {
...
return ret;
}

Of course, you can use function templates like this:

template <typename T> T& foo();
template <> std::string& foo<std::string>() { ... }
template <> int& foo<int>() { ... }

This also work with member function templates (in general, I would
not return references, though, unless there is a good reason to do
so...). Of course, you still need to specify the type you are
interested in.

A solution which is more involved for the implementer but even more
convenient for the user is the use of a proxy class. In this case,
'foo()' merely becomes some form of a function generator and the
actual execution is performed by the proxy:

struct foo_proxy
{
operator std::string&() const { ... }
operator int&() const { ... }
};

foo_proxy foo()
{
return foo_proxy();
}

This way, the compiler figures out which version of the function
shall be used.

Quote:
But is there a more elegant way? I'm not interested in variants and
such. I'm just looking for something that resembles overloading on
return value, with an aesthetically pleasing syntax.

I think both versions provided above fit these requirements although
the template is somewhat close to your approach...
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Antoun Kanawati
Guest





PostPosted: Mon Jun 27, 2005 5:01 pm    Post subject: Re: overloading on return value Reply with quote

[email]unspammable (AT) gmail (DOT) com[/email] wrote:
Quote:
A Java guy asked me, basically, how to overload a function on the type
of return value. In Java, he said, you just return Object and then cast
it to whatever you want (String, Integer)...

That's the total opposite of overloading; even in Java, overloading
means a compile time mechanism whereby the compiler figures out which
the function to call based on (static) argument types.

In C++, we don't have an Object class at the root of all hierarchies, so
it takes some extra work to do the sort of thing the Java guy is talking
about. But, even when you do that, you still don't have overloading:
the discovery of the intended return type and branching on that basis
are purely runtime behavior.
--
A. Kanawati
[email]NO.antounk.SPAM (AT) comcast (DOT) net[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
unspammable@gmail.com
Guest





PostPosted: Tue Jun 28, 2005 9:49 am    Post subject: Re: overloading on return value Reply with quote

You have it in Perl (and, apparently, as Chapin noted above, in Ada).
What I mean is the possiblity of having:
int foo();
string foo();

Which function is invoked depends on the variable into which the
returned value is assigned.
string s = foo(); // will invoke "string foo()"...

That's what I call overloading on return type. C++ doesn't have it,
still I want something similar.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
R.F. Pels
Guest





PostPosted: Tue Jun 28, 2005 9:49 am    Post subject: Re: overloading on return value Reply with quote

[email]unspammable (AT) gmail (DOT) com[/email] wrote:

Quote:
I explained that in C++ you can't overload on return value, but you can
do this:

string& foo(string& ret) {
...
return ret;
}

int& foo(int& ret) {
...
return ret;
}


Ad infinitum yes Smile You also could use the Visitor pattern. Not for
primitives though. But this really is the simplest form.


--
Ruurd
..o.
...o
ooo

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
unspammable@gmail.com
Guest





PostPosted: Tue Jun 28, 2005 9:50 am    Post subject: Re: overloading on return value Reply with quote

If I use the foo_proxy approach I get a proxy class whose instances can
contain either strings or ints. Essentially a variant, isn't it?
I'm not interested in having one function that can return an
ambiguously typed value, but in having two functions that differ only
in return type.

The template approach is nice, but, as you note, one has to specify the
type explicitly.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
unspammable@gmail.com
Guest





PostPosted: Tue Jun 28, 2005 9:51 am    Post subject: Re: overloading on return value Reply with quote

I didn't say I thought casting Objects to Integers or Strings is
overloading on return type. That's what my Java-turned-C++ friend had
in mind. What he acually needs, IMO, is overloading on returned value,
like in Perl. Since this isn't available in C++ I'm wondering what's
the closest thing.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
tony_in_da_uk@yahoo.co.uk
Guest





PostPosted: Tue Jun 28, 2005 10:42 am    Post subject: Re: overloading on return value Reply with quote

Amusing that replies tend to either focus on the mistaken "overload"
terminology, quote back your own example, or give you a variant
implementation. Of course, it is silly to say "I'm not interested in
variants" - what do you think Java's internal implementation is?
Further, while I agree most C++ variant implementations encountered in
the field are pathetic, I'm aware of three genuinely reusable and
elegant approaches, each with their own pros and cons. There's the
"capture the typeinfo and yield the value if you guess the type", the
enumerated variant<typelist> approach, and you can also use an abstract
base class template and instantiate it in templated constructors /
operator=, `saving' the behaviours that the stored types must be able
to provide in a VDT.

Anyway, ignoring variants, there are a couple other bodgy but workable
approaches which aren't much worse than Java's: you can serialise
(externalise in Java speak) into a return variable, allowing the user
to try to stream the value back in to variables of various types.
Similarly, you can return a string representation (lexical_cast<>?).

Cheers, Tony


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Martin Bonner
Guest





PostPosted: Tue Jun 28, 2005 12:06 pm    Post subject: Re: overloading on return value Reply with quote



[email]unspammable (AT) gmail (DOT) com[/email] wrote:
Quote:
If I use the foo_proxy approach I get a proxy class whose instances can
contain either strings or ints. Essentially a variant, isn't it?

No, that is not what the proxy class does.

Dietmar Kuehl wrote:
Quote:
struct foo_proxy
{
operator std::string&() const { ... } // A
operator int&() const { ... } // B
};

foo_proxy foo()
{
return foo_proxy();
}

The code that you wanted to name "std::string& foo()" replaces the
"..." on line A, and the code that you wanted to name "int& foo()"
replaces the "..." on line B.

Of course, if the original foo() was a member function of class bar,
then foo_proxy would need to take contain a reference to bar, and might
well need to be a friend - but that is all detail

Quote:
I'm not interested in having one function that can return an
ambiguously typed value, but in having two functions that differ only
in return type.

Why can't you just call them fooString and fooInt? What benefit do you
gain from having the same name?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
simont
Guest





PostPosted: Tue Jun 28, 2005 1:09 pm    Post subject: Re: overloading on return value Reply with quote

[email]unspammable (AT) gmail (DOT) com[/email] wrote:
Quote:
If I use the foo_proxy approach I get a proxy class whose instances can
contain either strings or ints. Essentially a variant, isn't it?
I'm not interested in having one function that can return an
ambiguously typed value, but in having two functions that differ only
in return type.

Not necessarily. Although two functions can't differ only by return
type, the proxy can forward back to the original class, like so:

class X
{
public:
string& foo_string();
int foo_int();

class OverloadedReturnProxy
{
X& x_;
public:
OverloadedReturnProxy(X& x): x_(x) {}

operator string&() { return x_.foo_string(); }
operator int() { return x_.foo_int(); }
};

OverloadedReturnProxy foo()
{
return OverloadedReturnProxy(*this);
}
};

This class X::OverloadedReturnProxy isn't a variant, it is just there
as syntactic sugar (along with x::foo) so you can call X::foo_string,
X::foo_int and X::foo_Y with the same syntax.

Here, the X::foo_? methods differ only by return type insofar as you
can call all of them through the same name, X::foo(). Code like

string s = x.foo();
int i = x.foo();

calls the two "overloads" of foo, foo_string and foo_int, and is wholly
dispatched at compile time. Is that good enough?


Quote:
The template approach is nice, but, as you note, one has to specify the
type explicitly.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.