Re: [opensuse-programming] C++ overload question.
Hi Jerry,
You could set up a zero-length vector as a global object outside of
a function. You could then use it as the default reference via:
std::vector<double> zero(0);
int foo(std::vector<double> & x, std::vector<double> & y=zero);
However, this is rather unsafe, as a non-const y (and, therefore,
zero) could be changed by foo (and the global, non-const zero could be
changed by any part of the code). If zero can be changed, we can not
guarantee that it will remain a zero-length vector. There are two
ways to address this problem.
First, if y is not altered within foo, then just make both zero
and y const quantities:
const std::vector<double> zero(0);
int foo(std::vector<double> & x, const std::vector<double> & y=zero);
The second way, as Verdi suggsted, is to overload foo:
int foo(std::vector<double> & x, std::vector<double> & y);
int foo(std::vector<double> & x)
{
std::vector<double> y;
return foo(x, y);
}
Of these two options, the second is safest, as the y vector
declared within foo can not interfere with any other parts of your
code (i.e., it can not be used anywhere else, unlike a global). When
possible, I try to find ways to reduce the number of functions I write
(and thus maximize code reuse), but I do not see the advantage of
using a single function definition with a default value as in the
first case. (And, in effect, there is only one function foo in the
second case, as both functions end up using the code within foo(x,
y).)
Have you come across a situation like this where overloading is
not preferable? I would be interested in finding out.
Take care!
- Nathan
--
Nathan C. Hearn
nhearn@uchicago.edu
ASC Flash Center
Computational Physics Group
University of Chicago
On 4/3/07, Jerry Feldman
In porting some code I have a function (this is the original code). The second parameter has a default. Array is a home grown class. int foo(Array<aaa> &x, Array<bbb> *y = NULL);
What I want is to replace the home grown array classes with the STL vector class. I also want to pass them by reference. int foo(std::vector<aaa> &x, std::vector<bbb> &y); But, this requires 2 parameters. Using vector, I could overload foo with an inline single argument function that would achieve the desired result. inline int foo(std::vector<aaa> &x) { std::vector<bbb> y; // empty vector return foo(x, y); }
Is there a good way where I could use a single function call, using vector where the second parameter has a default value as the empty vector. This would also achieve the desired result, but with a performance hit if vector y is populated. int foo(std::vector<aaa> &x, std::vector<bbb> *y =NULL); -- Jerry Feldman
Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Thanks Nathan,
Whose Verdi?
In any case, before I submitted this I did set up the second function.
I believe that the second parameter is const in this case, so the
setting up of a const empty vector works also.
On Tue, 3 Apr 2007 23:15:59 -0500
"Nathan Hearn"
Hi Jerry,
You could set up a zero-length vector as a global object outside of a function. You could then use it as the default reference via:
std::vector<double> zero(0);
int foo(std::vector<double> & x, std::vector<double> & y=zero);
However, this is rather unsafe, as a non-const y (and, therefore, zero) could be changed by foo (and the global, non-const zero could be changed by any part of the code). If zero can be changed, we can not guarantee that it will remain a zero-length vector. There are two ways to address this problem.
First, if y is not altered within foo, then just make both zero and y const quantities:
const std::vector<double> zero(0);
int foo(std::vector<double> & x, const std::vector<double> & y=zero);
The second way, as Verdi suggsted, is to overload foo:
int foo(std::vector<double> & x, std::vector<double> & y);
int foo(std::vector<double> & x) { std::vector<double> y; return foo(x, y); }
Of these two options, the second is safest, as the y vector declared within foo can not interfere with any other parts of your code (i.e., it can not be used anywhere else, unlike a global). When possible, I try to find ways to reduce the number of functions I write (and thus maximize code reuse), but I do not see the advantage of using a single function definition with a default value as in the first case. (And, in effect, there is only one function foo in the second case, as both functions end up using the code within foo(x, y).)
Have you come across a situation like this where overloading is not preferable? I would be interested in finding out.
Take care!
- Nathan
-- Nathan C. Hearn nhearn@uchicago.edu
ASC Flash Center Computational Physics Group University of Chicago
On 4/3/07, Jerry Feldman
wrote: In porting some code I have a function (this is the original code). The second parameter has a default. Array is a home grown class. int foo(Array<aaa> &x, Array<bbb> *y = NULL);
What I want is to replace the home grown array classes with the STL vector class. I also want to pass them by reference. int foo(std::vector<aaa> &x, std::vector<bbb> &y); But, this requires 2 parameters. Using vector, I could overload foo with an inline single argument function that would achieve the desired result. inline int foo(std::vector<aaa> &x) { std::vector<bbb> y; // empty vector return foo(x, y); }
Is there a good way where I could use a single function call, using vector where the second parameter has a default value as the empty vector. This would also achieve the desired result, but with a performance hit if vector y is populated. int foo(std::vector<aaa> &x, std::vector<bbb> *y =NULL); -- Jerry Feldman
Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
--
Jerry Feldman
For some reason, I did not receive Verdi's message, only Nathan's, but
I then found it in the archives.
In any case, thanks for the responses.
The case where overloading is not preferable is performance.
In the overloading case:
inline int foo(std::vector<aaa> &x) {
std::vector<bbb> y; // empty vector
return foo(x, y);
}
The default empty vector, y must be instantiated each time the function
is called. In the non-overloading case:
const std::vector<bbb> zero(0);
The vector zero is only instantiated once at run-time.
In the code I am porting, some of the functions take a number of
arguments with some being default arguments. Since I am essentially
taking only part of the original code as the basis for a new product, I
can take considerable liberties by eliminating things that we don't
want. (The original code was written before the STL was standardized.
One of our design parameters is to use either the STL or RogueWave to
implement containers and strings rather than the original home-grown
classes. One reason for RogueWave is that its STL is threadsafe where
the Linux STL implementation is not).
--
Jerry Feldman
participants (2)
-
Jerry Feldman
-
Nathan Hearn