By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,978 Members | 1,467 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,978 IT Pros & Developers. It's quick & easy.

returning references

P: n/a
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE

I have never heard anyone else say that it is a problem for a function
to return a reference. Are there really experts who object, or is
this nothing other than the commonplace observation that reference-
returning is a somewhat difficult concept that needs to be learned
carefully? (I am just learning about this now.) Assuming programmers
have some degree of competence and are able to avoid returning
references to locals and so on, what (if anything) are the pitfalls?

Paul Epstein
Jan 4 '08 #1
Share this Question
Share on Google+
23 Replies


P: n/a
On Jan 3, 6:26 pm, pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE

I have never heard anyone else say that it is a problem for a function
to return a reference. Are there really experts who object, or is
this nothing other than the commonplace observation that reference-
returning is a somewhat difficult concept that needs to be learned
carefully? (I am just learning about this now.) Assuming programmers
have some degree of competence and are able to avoid returning
references to locals and so on, what (if anything) are the pitfalls?

Paul Epstein
I don't see anything at all with returning references as long as the
const keyword is used correctly when appropriate. Surprisingly, a good
number of people do not use const when creating thier function stubs;

const MyClass & GetMyClass() const; // The typical accessor
SetMyClass(const MyClass & myclass); // The typical mutator

I constantly find the above two methods lacking the const keyword in
source when I am debugging and it leads to misuse by other programmers
who simply glance at a method without taking into account the impact
of making changes to the returned reference.

Another common problem I run into is you can't return NULL for a
reference. Sometimes it is nice to have the option to return NULL when
an error occured in which case I use a pointer and tell the caller to
check the returned value to determine if an error occured. Some people
don't like that idea though, but it is worth mentioning.
Jan 4 '08 #2

P: n/a
On 2008-01-04 01:26, pa**********@att.net wrote:
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE

I have never heard anyone else say that it is a problem for a function
to return a reference. Are there really experts who object, or is
this nothing other than the commonplace observation that reference-
returning is a somewhat difficult concept that needs to be learned
carefully? (I am just learning about this now.) Assuming programmers
have some degree of competence and are able to avoid returning
references to locals and so on, what (if anything) are the pitfalls?
As far as I know there is only one pitfall, and that is returning a
reference to a variable local to the function, like so:

int& foo(int i)
{
int r = i+i;
return r;
}

int main()
{
int& twice = foo(5);
}

Since r is a local variable to foo() it will go out of scope as soon as
foo() is done executing, this means that the reference returned refers
to a variable that no longer exists.

On the other hand there are a number of valid reasons to return a
reference from a function, a function that returns an element from a
collection is a good example (look at the at() function in std::vector).

--
Erik Wikström
Jan 4 '08 #3

P: n/a
On Jan 4, 12:26*am, pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE
hmmm... I assume that following this extremely wise and useful advice,
Stanford students will not be allowed to do ...

#include <iostream>
int main(){
std::cout << "hello world\n";
}
regards
Andy Little

(Thankfully Not a C++ expert!) :-)
Jan 4 '08 #4

P: n/a
pa**********@att.net wrote:
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never
returning a reference from a function or method.
QUOTE ENDS HERE

I have never heard anyone else say that it is a problem for a
function to return a reference.
"C++ Coding Standards" by Sutter & Alexandrescu. Item 42: Don't give
away your internals.

Don't volunteer too much: Avoid returning handles to internal data
managed by your class, so clients won't uncontrollably modify
state that your object thinks it owns.

For context, "handles" above is defined as non-const references, and
pointers to non-const data.

So now you have heard of at least two acknowledged experts who almost
state the same thing.
Are there really experts who object, or is this nothing other than
the commonplace observation that reference- returning is a somewhat
difficult concept that needs to be learned carefully? (I am just
learning about this now.) Assuming programmers have some degree of
competence and are able to avoid returning references to locals and
so on, what (if anything) are the pitfalls?
The only valid reference that can be returned from a non-member function
is something that either the calling code had access to anyway, or
something that is buried in a module.

The only valid reference that can be returned from a member-function is
of something that either the calling code had access to anyway, or
something that is private within the class.

In either case, if you are returning a non-const reference, then the
object returned better not have anything to do with the invariant of
that class/module or the class/module is asking for trouble
(encapsulation is broken.)
Jan 4 '08 #5

P: n/a
On Jan 3, 11:14 pm, "Daniel T." <danie...@earthlink.netwrote:
pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.
QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never
returning a reference from a function or method.
QUOTE ENDS HERE
I have never heard anyone else say that it is a problem for a
function to return a reference.

"C++ Coding Standards" by Sutter & Alexandrescu. Item 42: Don't give
away your internals.

Don't volunteer too much: Avoid returning handles to internal data
managed by your class, so clients won't uncontrollably modify
state that your object thinks it owns.

For context, "handles" above is defined as non-const references, and
pointers to non-const data.

So now you have heard of at least two acknowledged experts who almost
state the same thing.
I beg to differ with the statement that two quotes from so called
experts _almost_ say the same thing. They are extremely different
considering the impact of const correctness. the former quote is
moronic and the latter is imo quite correct.

Are there really experts who object, or is this nothing other than
the commonplace observation that reference- returning is a somewhat
difficult concept that needs to be learned carefully? (I am just
learning about this now.) Assuming programmers have some degree of
competence and are able to avoid returning references to locals and
so on, what (if anything) are the pitfalls?

The only valid reference that can be returned from a non-member function
is something that either the calling code had access to anyway, or
something that is buried in a module.

The only valid reference that can be returned from a member-function is
of something that either the calling code had access to anyway, or
something that is private within the class.
What's stopping me from returning a reference to protected data
exactly?
In either case, if you are returning a non-const reference, then the
object returned better not have anything to do with the invariant of
that class/module or the class/module is asking for trouble
(encapsulation is broken.)
agreed.
Jan 4 '08 #6

P: n/a
On Jan 3, 7:26 pm, pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE

I have never heard anyone else say that it is a problem for a function
to return a reference. Are there really experts who object, or is
this nothing other than the commonplace observation that reference-
returning is a somewhat difficult concept that needs to be learned
carefully? (I am just learning about this now.) Assuming programmers
have some degree of competence and are able to avoid returning
references to locals and so on, what (if anything) are the pitfalls?

Paul Epstein
Nothing wrong in returning references, example: various operators.
You already coverred the case of returning a temporary.
One pitfall is side-effects where an accessor might _get_ nasty.
Thats where CV-qualifiers play an important role.

#include <iostream>
#include <ostream>

class N
{
int m_n;
public:
N(int n) : m_n(n) { }
// accessors
int& getnasty() { return m_n; } // nasty
int const& getsafe() const { return m_n; }
void set(const int& n) { m_n = n; }
// friend op<<
friend std::ostream&
operator<<(std::ostream& os, const N& r)
{
return os << r.m_n;
}
};

int main()
{
N instance(9);
std::cout << instance << std::endl;

instance.getnasty() = -1; // nasty side-effect
std::cout << instance << std::endl;

instance.set(8);
std::cout << instance << std::endl;
std::cout << instance.getsafe() << std::endl;
}

/*
9
-1
8
8
*/
Jan 4 '08 #7

P: n/a
kwikius wrote:
On Jan 4, 12:26 am, pauldepst...@att.net wrote:
>Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE

hmmm... I assume that following this extremely wise and useful advice,
Stanford students will not be allowed to do ...

#include <iostream>
int main(){
std::cout << "hello world\n";
well this is allowed, while
std::cout << "hello world" << std::endl;
is not,

write
std::cout << "hello world";
std::cout << std::endl;
instead.

:D
}
regards
Andy Little

(Thankfully Not a C++ expert!) :-)
Jan 4 '08 #8

P: n/a
On Jan 4, 6:48 am, Christopher <cp...@austin.rr.comwrote:
On Jan 3, 11:14 pm, "Daniel T." <danie...@earthlink.netwrote:
pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.
QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never
returning a reference from a function or method.
QUOTE ENDS HERE
I have never heard anyone else say that it is a problem for a
function to return a reference.
"C++ Coding Standards" by Sutter & Alexandrescu. Item 42: Don't give
away your internals.
Don't volunteer too much: Avoid returning handles to internal data
managed by your class, so clients won't uncontrollably modify
state that your object thinks it owns.
For context, "handles" above is defined as non-const references, and
pointers to non-const data.
So now you have heard of at least two acknowledged experts who almost
state the same thing.
I beg to differ with the statement that two quotes from so called
experts _almost_ say the same thing. They are extremely different
considering the impact of const correctness. the former quote is
moronic and the latter is imo quite correct.
The real difference is that they are addressing two radically
different levels. The Sutter/Alexandrescu quote has nothing to
do with references per se, but is more concerned with design;
I'm sure that neither Sutter nor Alexandrescu would condemn
std::vector<>::operator[] because it returns a reference (to
internal data, no less), nor the operator<< and operator>in
iostream because they return a reference to support chaining.
(Alexandrescu definitly doesn't like iostream, but I don't think
that the fact that operator<< returns a reference has anything
to do with it.)

The real difference is that Sutter and Alexandrescu address a
real issue with their comment: how to intelligently design a
class. Where as the quoted recommendation simply misses the
point entirely, by concentrating on an irrelevant syntax issue.
(How is returning a reference riskier than returning a pointer,
for example?)
Are there really experts who object, or is this nothing
other than the commonplace observation that reference-
returning is a somewhat difficult concept that needs to be
learned carefully? (I am just learning about this now.)
Assuming programmers have some degree of competence and
are able to avoid returning references to locals and so
on, what (if anything) are the pitfalls?
The only valid reference that can be returned from a
non-member function is something that either the calling
code had access to anyway, or something that is buried in a
module.
The only valid reference that can be returned from a
member-function is of something that either the calling code
had access to anyway, or something that is private within
the class.
What's stopping me from returning a reference to protected
data exactly?
In either case, if you are returning a non-const reference,
then the object returned better not have anything to do with
the invariant of that class/module or the class/module is
asking for trouble (encapsulation is broken.)
agreed.
But what does that say, anyway? And how is returning a
reference any more of a problem here than returning a pointer.

There are two issues with returning a reference; permitting
access to internal details, and the lifetime of what is referred
to. They're both design issues, both affect other constructs as
well, and neither affects all use of references. Many standard
idioms and patterns involve returning references, and I've never
heard of any expert who recommended never returning a reference.

--
James Kanze (GABI Software) mailto:ja*********@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
Jan 4 '08 #9

P: n/a
On 2008-01-04 10:29, Barry wrote:
kwikius wrote:
>On Jan 4, 12:26 am, pauldepst...@att.net wrote:
>>Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE

hmmm... I assume that following this extremely wise and useful advice,
Stanford students will not be allowed to do ...

#include <iostream>
int main(){
std::cout << "hello world\n";

well this is allowed, while
std::cout << "hello world" << std::endl;
is not,

write
std::cout << "hello world";
std::cout << std::endl;
instead.
The reference will be returned regardless if you use it or not, but I
guess they make an exception for library functions :-)

PS. Please do not quote signatures

--
Erik Wikström
Jan 4 '08 #10

P: n/a
Christopher <cp***@austin.rr.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.
QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never
returning a reference from a function or method.
QUOTE ENDS HERE
I have never heard anyone else say that it is a problem for a
function to return a reference.
"C++ Coding Standards" by Sutter & Alexandrescu. Item 42: Don't give
away your internals.

Don't volunteer too much: Avoid returning handles to internal data
managed by your class, so clients won't uncontrollably modify
state that your object thinks it owns.

For context, "handles" above is defined as non-const references, and
pointers to non-const data.

So now you have heard of at least two acknowledged experts who almost
state the same thing.

I beg to differ with the statement that two quotes from so called
experts _almost_ say the same thing. They are extremely different
considering the impact of const correctness. the former quote is
moronic and the latter is imo quite correct.
Only if you assume that the former quote includes "const reference" when
it says "reference". It may not.

My personal standing rule is, "functions return const reference, pointer
to const, or by object, unless they are returning one of the parameters
passed in." (Of course there are exceptions, there are exceptions to
every rule, but if I find myself returning a non-const reference or a
pointer to a non-const object, I make sure I have a real good reason.)
Are there really experts who object, or is this nothing other than
the commonplace observation that reference- returning is a somewhat
difficult concept that needs to be learned carefully? (I am just
learning about this now.) Assuming programmers have some degree of
competence and are able to avoid returning references to locals and
so on, what (if anything) are the pitfalls?
The only valid reference that can be returned from a non-member function
is something that either the calling code had access to anyway, or
something that is buried in a module.

The only valid reference that can be returned from a member-function is
of something that either the calling code had access to anyway, or
something that is private within the class.

What's stopping me from returning a reference to protected data
exactly?
Granted. The point of the post is that if you are returning a non-const
reference to something the calling code doesn't have access to (for
whatever reason,) you are probably making a mistake.

I suspect that at this point, any difference between our positions is
merely picking nits.
Jan 4 '08 #11

P: n/a
Daniel T. wrote:
:: pa**********@att.net wrote:
::
::: Below is posted from a link for Stanford students in computer
::: science.
:::
::: QUOTE BEGINS HERE
::: Because of the risk of misuse, some experts recommend never
::: returning a reference from a function or method.
::: QUOTE ENDS HERE
:::
::: I have never heard anyone else say that it is a problem for a
::: function to return a reference.
::
:: "C++ Coding Standards" by Sutter & Alexandrescu. Item 42: Don't
:: give away your internals.
::
:: Don't volunteer too much: Avoid returning handles to internal
:: data managed by your class, so clients won't uncontrollably
:: modify state that your object thinks it owns.
::
:: For context, "handles" above is defined as non-const references,
:: and pointers to non-const data.
::
:: So now you have heard of at least two acknowledged experts who
:: almost state the same thing.
::
::: Are there really experts who object, or is this nothing other than
::: the commonplace observation that reference- returning is a
::: somewhat difficult concept that needs to be learned carefully?
::: (I am just learning about this now.) Assuming programmers have
::: some degree of competence and are able to avoid returning
::: references to locals and so on, what (if anything) are the
::: pitfalls?
::
:: The only valid reference that can be returned from a non-member
:: function is something that either the calling code had access to
:: anyway, or something that is buried in a module.
::
:: The only valid reference that can be returned from a
:: member-function is of something that either the calling code had
:: access to anyway, or something that is private within the class.
::
:: In either case, if you are returning a non-const reference, then
:: the object returned better not have anything to do with the
:: invariant of that class/module or the class/module is asking for
:: trouble (encapsulation is broken.)

But even if you return a const reference to internal data, the
encapsulation is still broken - just a bit less. By returning a
reference, you have promised to somehow keep the referred-to object.
If you return by value, you are more free to change your
implementation later.
Also, we should all note that Sutter & Alexandrescu say "avoid" in
their guidelines, not "never do this". That's an important difference!
Bo Persson
Jan 4 '08 #12

P: n/a
"Bo Persson" <bo*@gmb.dkwrote:
But even if you return a const reference to internal data, the
encapsulation is still broken - just a bit less. By returning a
reference, you have promised to somehow keep the referred-to object.
If you return by value, you are more free to change your
implementation later.
Changing a function from returning const-reference to returning const
object can't break any existing clients.

IE. if I have this:

class Object {
public:
const Foo& getFoo() const;
};

and later, I don't want to store a Foo, I can easily change the class to:

class Object {
public:
const Foo getFoo() const; // I could even dump the first const
};

and clients will not be affected. As I understand it, the two returns
are as interchangeable as if they were function parameters.

At least this is my understanding...
Jan 4 '08 #13

P: n/a
On Jan 4, 8:36 pm, "Daniel T." <danie...@earthlink.netwrote:
Changing a function from returning const-reference to returning const
object can't break any existing clients.
IE. if I have this:
class Object {
public:
const Foo& getFoo() const;
};
and later, I don't want to store a Foo, I can easily change
the class to:
class Object {
public:
const Foo getFoo() const; // I could even dump the first const
};
and clients will not be affected. As I understand it, the two
returns are as interchangeable as if they were function
parameters.
Unless, of course, the type doesn't support copy. Or if the
client takes the address of the return, and later uses it. Or
any number of other cases as well. The lifetime of the object
is *not* the same.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Jan 4 '08 #14

P: n/a
James Kanze <ja*********@gmail.comwrote:
On Jan 4, 8:36 pm, "Daniel T." <danie...@earthlink.netwrote:
Changing a function from returning const-reference to returning const
object can't break any existing clients.
IE. if I have this:
class Object {
public:
const Foo& getFoo() const;
};
and later, I don't want to store a Foo, I can easily change
the class to:
class Object {
public:
const Foo getFoo() const; // I could even dump the first const
};
and clients will not be affected. As I understand it, the two
returns are as interchangeable as if they were function
parameters.

Unless, of course, the type doesn't support copy. Or if the
client takes the address of the return, and later uses it. Or
any number of other cases as well. The lifetime of the object
is *not* the same.
Well, in the former case, Object has no choice but to return a reference
(or pointer.) In the latter case... I don't concern myself with such
pathological behavior by the client. I don't guarantee that state
returned by const reference will last past the next sequence point in
any case.
Jan 5 '08 #15

P: n/a
On Jan 5, 1:57 am, "Daniel T." <danie...@earthlink.netwrote:

[...]
Unless, of course, the type doesn't support copy. Or if the
client takes the address of the return, and later uses it. Or
any number of other cases as well. The lifetime of the object
is *not* the same.
Well, in the former case, Object has no choice but to return a
reference (or pointer.)
And the case is rather frequent, don't you think.
In the latter case... I don't concern myself with such
pathological behavior by the client. I don't guarantee that
state returned by const reference will last past the next
sequence point in any case.
In sum, you require the results of a lookup in a map to be used
in the expression doing the lookup, and not later. That's very,
very counter-intuitive and unexpected. And also very difficult
to use correctly, since the client does have to test whether the
lookup found something before using it.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Jan 5 '08 #16

P: n/a
James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
Jame Kanze wrote:
Daniel T wrote:
[Returning a const-reference to internal state can be
converted to a return of a const object of that state]
>
Unless, of course, the type doesn't support copy. Or if the
client takes the address of the return, and later uses it. Or
any number of other cases as well. The lifetime of the object
is *not* the same.
Well, in the former case, Object has no choice but to return a
reference (or pointer.)

And the case is rather frequent, don't you think.
That depends on how often you use value semantics.
[What] if the client takes the address of [a const-reference]
return, and later uses it.
In the latter case... I don't concern myself with such
pathological behavior by the client. I don't guarantee that state
returned by const reference will last past the next sequence
point in any case.

In sum, you require the results of a lookup in a map to be used in
the expression doing the lookup, and not later. That's very, very
counter-intuitive and unexpected. And also very difficult to use
correctly, since the client does have to test whether the lookup
found something before using it.
A map does not return a non-const reference to any internal state, so I
don't see how that relates in any way.
Jan 5 '08 #17

P: n/a
James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
A map does not return a non-const reference to any internal
state, so I don't see how that relates in any way.

std::map certainly does return references to internal state, as
does every other map I've every seen or heard of.
Really, could you give an example? Maybe I'm mistaken...
Jan 5 '08 #18

P: n/a
Daniel T. wrote:
James Kanze <ja*********@gmail.comwrote:
>"Daniel T." <danie...@earthlink.netwrote:
A map does not return a non-const reference to any internal
state, so I don't see how that relates in any way.

std::map certainly does return references to internal state, as
does every other map I've every seen or heard of.

Really, could you give an example? Maybe I'm mistaken...
std::map< int, int the_map;
...
the_map[5] = 6; // the_map[5] returns an int&.

I conjecture that the two of you are in disagreement about whether that is
an "internal state" of the map. Since I have no idea what "internal state"
is supposed to mean with regard to std::map, I will not offer an opinion.
Best

Kai-Uwe Bux
Jan 5 '08 #19

P: n/a
jk********@gmx.net wrote:
Daniel T. wrote:
James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
A map does not return a non-const reference to any internal
state, so I don't see how that relates in any way.
>
std::map certainly does return references to internal state, as
does every other map I've every seen or heard of.
Really, could you give an example? Maybe I'm mistaken...

std::map< int, int the_map;
...
the_map[5] = 6; // the_map[5] returns an int&.

I conjecture that the two of you are in disagreement about whether
that is an "internal state" of the map. Since I have no idea what
"internal state" is supposed to mean with regard to std::map, I
will not offer an opinion.
Right, that is not internal state, I define "internal state" as state
that is part of the invariant of the class. Does changing the state of
the object returned by map::operator[] have any chance of breaking any
of the map's invariants? No.

Note, that the map class doesn't return a non-const reference from the
"size()" member-function. It could return either by value or by const
reference, either would be safe (assuming appropriate internal changes,)
and switching back in forth between them would not affect code that uses
map::size() in the slightest. (If it *did* affect code that uses the
member-function, the it is the calling code that is messed up.)
[What] if the client takes the address of [a const-reference]
return, and later uses it.
When James said the above, I took it to mean something like the example
below.

class Foo {
public:
const Bar& get() const;
};

void bad_client( Foo& foo ) {
const Bar* b = &foo.get();
// then do things, assuming that 'b' will continue to be
// valid no matter what I may do to 'foo'.
}

I consider such code to be inherently dangerous... When what is returned
is a const-reference to internal state, the calling code shouldn't
assume 'b's validity even past the ';' of the get call.
Jan 5 '08 #20

P: n/a
Daniel T. a crit :
jk********@gmx.net wrote:
>Daniel T. wrote:
>>James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
A map does not return a non-const reference to any internal
state, so I don't see how that relates in any way.
std::map certainly does return references to internal state, as
does every other map I've every seen or heard of.
Really, could you give an example? Maybe I'm mistaken...
std::map< int, int the_map;
...
the_map[5] = 6; // the_map[5] returns an int&.

I conjecture that the two of you are in disagreement about whether
that is an "internal state" of the map. Since I have no idea what
"internal state" is supposed to mean with regard to std::map, I
will not offer an opinion.

Right, that is not internal state, I define "internal state" as state
that is part of the invariant of the class. Does changing the state of
the object returned by map::operator[] have any chance of breaking any
of the map's invariants? No.
Since the lifetime of the object is managed by map<>, the returned value
references an internal state and it is clearly specified which
operations invalidate such objects: a call to clear() by example or
possibly a push_back in the case of vector<>.
>
Note, that the map class doesn't return a non-const reference from the
"size()" member-function. It could return either by value or by const
reference, either would be safe (assuming appropriate internal changes,)
and switching back in forth between them would not affect code that uses
map::size() in the slightest. (If it *did* affect code that uses the
member-function, the it is the calling code that is messed up.)
Technically, both are posible but a reference semantic would be counter
intuitive on a state you cannot change or share reliably.
>
>>>[What] if the client takes the address of [a const-reference]
return, and later uses it.

When James said the above, I took it to mean something like the example
below.

class Foo {
public:
const Bar& get() const;
};

void bad_client( Foo& foo ) {
const Bar* b = &foo.get();
// then do things, assuming that 'b' will continue to be
// valid no matter what I may do to 'foo'.
}

I consider such code to be inherently dangerous... When what is returned
is a const-reference to internal state, the calling code shouldn't
assume 'b's validity even past the ';' of the get call.

That depends on the contract you have with Foo. If it is a singleton or
a scoped_ptr<by example, there is nothing wrong.

Michael
Jan 6 '08 #21

P: n/a
James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
jkherci...@gmx.net wrote:
Daniel T. wrote:
James Kanze <james.ka...@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
>
A map does not return a non-const reference to any internal
state, so I don't see how that relates in any way.
>
std::map certainly does return references to internal state, as
does every other map I've every seen or heard of.

Really, could you give an example? Maybe I'm mistaken...
>
std::map< int, int the_map;
...
the_map[5] = 6; // the_map[5] returns an int&.
>
I conjecture that the two of you are in disagreement about whether
that is an "internal state" of the map. Since I have no idea what
"internal state" is supposed to mean with regard to std::map, I
will not offer an opinion.
Right, that is not internal state, I define "internal state"
as state that is part of the invariant of the class. Does
changing the state of the object returned by map::operator[]
have any chance of breaking any of the map's invariants? No.
I'm willing to drop the whole thing, it's my style, but I still want to
cover the issue you bring up below.
But the fact that the element exists, in the map, is part of the
maps internal state. You can't change this via the reference,
but you can certainly change it via other functions, while the
reference is still present.
The key to the above sentence is "you". *You* (i.e., the client using
the map) can "change it", the map cannot do so itself. In fact, the map
is specifically forbidden by the interface to remove/add an object
unless directed by certain special functions, and specifically required
to remove/add one when directed. The fact that the elements exist are
not "internal state".
E.g.:

std::map< int, int theMap ;
int& r = theMap[ 5 ] ;
theMap.erase( 5 ) ;
// ...

The presence or absense of the element in the map *is* part of
the map's internal state. And a reference to the element is
thus also part of the map's internal state, since it designates
something under control of the map.
I don't agree. The map has no control over when the client will call
erase, and it must do the erasure when the client does call the
member-function. The map doesn't control the lifetime of the object
anymore than your bank controls what you do with your money.
Jan 6 '08 #22

P: n/a
Michael DOUBEZ <mi************@free.frwrote:
Daniel T. a crit :
jk********@gmx.net wrote:
Daniel T. wrote:
James Kanze <ja*********@gmail.comwrote:
"Daniel T." <danie...@earthlink.netwrote:
>>>A map does not return a non-const reference to any internal
state, so I don't see how that relates in any way.
std::map certainly does return references to internal state, as
does every other map I've every seen or heard of.
Really, could you give an example? Maybe I'm mistaken...
std::map< int, int the_map;
...
the_map[5] = 6; // the_map[5] returns an int&.

I conjecture that the two of you are in disagreement about whether
that is an "internal state" of the map. Since I have no idea what
"internal state" is supposed to mean with regard to std::map, I
will not offer an opinion.
Right, that is not internal state, I define "internal state" as state
that is part of the invariant of the class. Does changing the state of
the object returned by map::operator[] have any chance of breaking any
of the map's invariants? No.

Since the lifetime of the object is managed by map<>, the returned value
references an internal state and it is clearly specified which
operations invalidate such objects: a call to clear() by example or
possibly a push_back in the case of vector<>.
Covered in my reply to James... 'vector' is an interesting case. The
vector is required to not invalidate the reference if at the time of the
call capacity() size(). If that is not the case, then vector has some
control over the lifetime of the object referenced.
Note, that the map class doesn't return a non-const reference from the
"size()" member-function. It could return either by value or by const
reference, either would be safe (assuming appropriate internal changes,)
and switching back in forth between them would not affect code that uses
map::size() in the slightest. (If it *did* affect code that uses the
member-function, the it is the calling code that is messed up.)

Technically, both are posible but a reference semantic would be counter
intuitive on a state you cannot change or share reliably.
As I said to James, this is a style issue. To me, returning by const
reference is a low level optimization over returning by object. So for
example, if 'size()' returned an object that was very expensive to copy,
I would use a const reference (or pointer to const) return rather than a
by value return and I would fully expect that clients of the class treat
it as if it was a by value return anyway.
>>[What] if the client takes the address of [a const-reference]
return, and later uses it.
When James said the above, I took it to mean something like the example
below.

class Foo {
public:
const Bar& get() const;
};

void bad_client( Foo& foo ) {
const Bar* b = &foo.get();
// then do things, assuming that 'b' will continue to be
// valid no matter what I may do to 'foo'.
}

I consider such code to be inherently dangerous... When what is returned
is a const-reference to internal state, the calling code shouldn't
assume 'b's validity even past the ';' of the get call.

That depends on the contract you have with Foo. If it is a singleton or
a scoped_ptr<by example, there is nothing wrong.
Of course. The contract specifies control.
Jan 6 '08 #23

P: n/a
On Jan 4, 1:26 pm, pauldepst...@att.net wrote:
Below is posted from a link for Stanford students in computer
science.

QUOTE BEGINS HERE
Because of the risk of misuse, some experts recommend never returning
a
reference from a function or method.
QUOTE ENDS HERE
This is obvious garbage; for example it is sensible to write:
ostream & operator<<( ostream &, YourClass const &y );

(Not to mention misuse of 'method' and 'function' terminology).
Jan 7 '08 #24

This discussion thread is closed

Replies have been disabled for this discussion.