passing strings

J

J. Campbell

Suppose I have an object that is concatinatable (sp) using the '+'
operator (eg string). I have a function(func)that will do some work
to the object and return an int. For several reasons it is desirable
to have the ability to call the function like this:
int myvalue = func(obj1 + obj2);

because of this am I limited to passing by value? If I demand a pass
by reference, must my calling procedure look like this,

AnObj temp = obj1 + obj2;
intmyvalue = func(temp);

rather than concatinating inside the function parentheses? This second
method defeats the purpose of pass-by-reference, since it creates a
new object anyway.

I realize that I could make the function declaration look like
int func(AnObj&, AnObj&);
but this is undesirable since the function really only needs one
AnObj.

Any advice?

Joe
 
V

Victor Bazarov

J. Campbell said:
Suppose I have an object that is concatinatable (sp) using the '+'
operator (eg string). I have a function(func)that will do some work
to the object and return an int. For several reasons it is desirable
to have the ability to call the function like this:
int myvalue = func(obj1 + obj2);

because of this am I limited to passing by value?

No, you may pass by reference to a const object. A temporary will
be created. Make sure your operator + returns an object.
If I demand a pass
by reference, must my calling procedure look like this,

AnObj temp = obj1 + obj2;
intmyvalue = func(temp);

rather than concatinating inside the function parentheses? This second
method defeats the purpose of pass-by-reference, since it creates a
new object anyway.

Passing by a reference to const object allows you to avoid creating
an object (the system will do it for you). A reference to non-const
object cannot be used because it cannot be bound to a temporary.
I realize that I could make the function declaration look like
int func(AnObj&, AnObj&);
but this is undesirable since the function really only needs one
AnObj.

Any advice?

See above. HTH.

Victor
 
D

Dave

J. Campbell said:
Suppose I have an object that is concatinatable (sp) using the '+'
operator (eg string). I have a function(func)that will do some work
to the object and return an int. For several reasons it is desirable
to have the ability to call the function like this:
int myvalue = func(obj1 + obj2);

because of this am I limited to passing by value? If I demand a pass
by reference, must my calling procedure look like this,

AnObj temp = obj1 + obj2;
intmyvalue = func(temp);

rather than concatinating inside the function parentheses? This second
method defeats the purpose of pass-by-reference, since it creates a
new object anyway.

I realize that I could make the function declaration look like
int func(AnObj&, AnObj&);
but this is undesirable since the function really only needs one
AnObj.

Any advice?

Joe

Well, I'm not sure exactly what your goal is so I'm not sure I can offer
advice that will help, but I'll offer a couple of observations...

You noted the creation of a second object in this case:

AnObj temp = obj1 + obj2;
intmyvalue = func(temp);


Well, there is a second object created in this case too:

int myvalue = func(obj1 + obj2);

In this case, the object is an unseen temorary, but it is real nonetheless.
For this reason, you could pass only by *const* reference. A non-const
reference may not be bound to a temporary, only a const reference may be.
And of course, if your goal is to have the called function modify its
parameter, you're SOL. If, however, you're not wanting to pass by reference
to have the called function modify its parameter but rather for efficiencies
sake, you could then change the parameter to a const reference and make the
call func(obj1 + obj2);.

So, I'm not sure if this will help but I hope it does...
 
J

Jacques Labuschagne

J. Campbell said:
Suppose I have an object that is concatinatable (sp) using the '+'
operator (eg string). I have a function(func)that will do some work
to the object and return an int. For several reasons it is desirable
to have the ability to call the function like this:
int myvalue = func(obj1 + obj2);

because of this am I limited to passing by value? If I demand a pass
by reference, must my calling procedure look like this,

AnObj temp = obj1 + obj2;
intmyvalue = func(temp);

rather than concatinating inside the function parentheses? This second
method defeats the purpose of pass-by-reference, since it creates a
new object anyway.

The expression "ob1 + ob2" should always create a temporary, it
shouldn't modify ob1 or ob2 [*]. And as you say, one can't pass a
temporary to a function expecting T&. You may be able to pass
a temporary to a function expecting const T&, but you would
still create a temporary by using operator+.
If you just want to modify ob1 and pass that in, declare an
appropriate += operator, and call func(obj1+=obj2).

[*] The reason obj1+obj2 shouldn't modify its arguments is because
(IMHO) it's important for libraries to have a consitent flavour. It's
important that things work the way a user intuitively expects them to
work.
T i = 1, j = 4;
T k = i + j;
If operator+ modified either i or j you would quickly have users
abandoning your library in disgust because of this wholly unneccessary
quirk which makes it harder to learn.

Jacques
 
J

Jonathan Turkanis

J. Campbell said:
Suppose I have an object that is concatinatable (sp) using the '+'
operator (eg string). I have a function(func)that will do some work
to the object and return an int. For several reasons it is desirable
to have the ability to call the function like this:
int myvalue = func(obj1 + obj2);

because of this am I limited to passing by value? <snip>

No, you can pass by const reference.
If I demand a pass
by reference, must my calling procedure look like this,

AnObj temp = obj1 + obj2;
intmyvalue = func(temp);

rather than concatinating inside the function parentheses? This second
method defeats the purpose of pass-by-reference, since it creates a
new object anyway.

The expression obj1 + obj2 creates a temporary object even if it is
called using

int myvalue = func(obj1 + obj2);

The problem is that f (as currently formulated) needs a string object
representing the concatenated value, and none exists, so one must be
created somewhere.

If you don't ming modifying obj1, you can write:

int myvalue = func(obj1 += obj2);
I realize that I could make the function declaration look like
int func(AnObj&, AnObj&);
but this is undesirable since the function really only needs one
AnObj.

If f does need actually need to construct a concatenated string, but
can do its job by inspecting obj1 and obj2, then your last suggestion
is probably the way to go.

Jonathan
 
J

Joe C

<snip>

You guys are magic. Thanks for the speedy replies. When I read about
tempories, I didn't have enough basis to understand...so it did't sink
in...I guess this is the reason to continue reading reference material as
your knowledge-base increases, no?

Anyway...my base question was about wanting to avoid passing heavy objects,
and it appears that in this case, it cannot be avoided unless I pass a
reference for each object and don't concatinate.

Thanks very much for the help.
Joe
 
V

Victor Bazarov

Joe C said:
<snip>

You guys are magic. Thanks for the speedy replies. When I read about
tempories, I didn't have enough basis to understand...so it did't sink
in...I guess this is the reason to continue reading reference material as
your knowledge-base increases, no?

Anyway...my base question was about wanting to avoid passing heavy objects,
and it appears that in this case, it cannot be avoided unless I pass a
reference for each object and don't concatinate.

Without knowing what your function does, I'll take your word for it.
Yes, usually addition creates another object from the two involved.
However, you _could_ create such object that serves as a _result_ of
addition and stores the _references_ or pointers to the original two
objects, and does some tricks when asked for the value. I'll give
you an example based on std::string.

#include <string>

class ConcatResult {
std::string const &s1;
std::string const &s2;
public:
ConcatResult(std::string const& s1, std::string const& s2)
: s1(s1), s2(s2) {}
char operator [](std::string::size_type i) const {
if (i < s1.length())
return s1;
else
return s2[i - s1.length()];
}

int length() const { return s1.length() + s2.length(); }
operator std::string() const { return s1 + s2; } // lazy
};

int foo(ConcatResult const &pseudoString) {
return pseudoString.length();
}

#include <iostream>
int main() {
std::string s1("abc"), s2("def");

std::cout << "The concatenated string would be "
<< foo(ConcatResult(s1,s2)) << " chars long\n";
}

HTH

Victor
 

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
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top