 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
unspammable@gmail.com Guest
|
Posted: Mon Jun 27, 2005 10:48 am Post subject: overloading on return value |
|
|
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
|
Posted: Mon Jun 27, 2005 12:56 pm Post subject: Re: overloading on return value |
|
|
| 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
|
Posted: Mon Jun 27, 2005 12:58 pm Post subject: Re: overloading on return value |
|
|
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
|
Posted: Mon Jun 27, 2005 12:59 pm Post subject: Re: overloading on return value |
|
|
"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
|
Posted: Mon Jun 27, 2005 1:00 pm Post subject: Re: overloading on return value |
|
|
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
|
Posted: Mon Jun 27, 2005 4:28 pm Post subject: Re: overloading on return value |
|
|
| 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
|
Posted: Mon Jun 27, 2005 4:59 pm Post subject: Re: overloading on return value |
|
|
[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
|
Posted: Mon Jun 27, 2005 5:01 pm Post subject: Re: overloading on return value |
|
|
[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
|
Posted: Tue Jun 28, 2005 9:49 am Post subject: Re: overloading on return value |
|
|
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
|
Posted: Tue Jun 28, 2005 9:49 am Post subject: Re: overloading on return value |
|
|
[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 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
|
Posted: Tue Jun 28, 2005 9:50 am Post subject: Re: overloading on return value |
|
|
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
|
Posted: Tue Jun 28, 2005 9:51 am Post subject: Re: overloading on return value |
|
|
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
|
Posted: Tue Jun 28, 2005 10:42 am Post subject: Re: overloading on return value |
|
|
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
|
Posted: Tue Jun 28, 2005 12:06 pm Post subject: Re: overloading on return value |
|
|
[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
|
Posted: Tue Jun 28, 2005 1:09 pm Post subject: Re: overloading on return value |
|
|
[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 |
|
 |
|
|
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
|
|