473,396 Members | 1,599 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

an iterator question

Hello,

I learned that if we do "v.end()", then the returned iterator is a
temporary object and hence cannot be changed like

--v.end();

Why is the returned iterator a temporary pointer? I think when the
result of a function is returned, then a non-temporary object is
created, with value copied from the local temporary object. If the
code above still gets us a temporary object, then I think the non-temp-
object-creation hasn't taken place yet. Does it only happen if we do

p = v.end();

ie. assign v.end() to some variable?

It is also said that we can't modify it because it has a built in
type. I guess "build-in" means pointer type here. This sounds to me
as if we could modify the temporary object if it is of class type.
I'm quite confused....

Thanks,
Jess

Jun 15 '07 #1
7 1660
Jess wrote:
Hello,

I learned that if we do "v.end()", then the returned iterator is a
temporary object and hence cannot be changed like

--v.end();
Why? It can. If an object is *temporary* it does NOT mean that you
cannot change it. The problem here is that the value is effectively
lost right after you change it, unless you store it somewhere, like

it = --v.end();

Try this program in "debug" mode:
----------
#include <list>
#include <cassert>

int main()
{
std::list<intli;
li.push_back(1);
li.push_back(2);
std::list<int>::iterator it = --li.end();
assert(*it == 2);
}
----------
Does the assertion fail?
>
Why is the returned iterator a temporary pointer?
A temporary pointer? WHAT???
I think when the
result of a function is returned, then a non-temporary object is
created, with value copied from the local temporary object. If the
code above still gets us a temporary object, then I think the
non-temp- object-creation hasn't taken place yet. Does it only
happen if we do

p = v.end();

ie. assign v.end() to some variable?
Huh? You lost me.
It is also said that we can't modify it because it has a built in
type.
"It is also said" *where*?? What is it that you're reading that is
so wrong?
I guess "build-in" means pointer type here. This sounds to me
as if we could modify the temporary object if it is of class type.
I'm quite confused....
It makes two of us.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 15 '07 #2
Victor Bazarov wrote:
Jess wrote:
>>
I learned that if we do "v.end()", then the returned iterator is a
temporary object and hence cannot be changed like

--v.end();

Why? It can. If an object is *temporary* it does NOT mean that you
cannot change it. The problem here is that the value is effectively
lost right after you change it, unless you store it somewhere, like

it = --v.end();
Depending on how the iterator's operator-- is written, it also might not
be legal. The subtlety here is that you can call non-const member
functions on a temporary object, but you cannot pass a temporary object
to a function through a non-const reference. The standard doesn't say
whether operator-- is a member function, just that --iter is valid and
has the appopriate effects.

struct iter1
{
iter1& operator--();
};
iter1 get1();

struct iter2
{
};
iter2& operator--(iter2&);
iter2 get2();

void f()
{
iter1 it1 = --get1(); // okay: calls iter1::operator--
iter2 it2 = --get2(); // error: can't call operator--(iter2&)
}

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Jun 15 '07 #3
Pete Becker wrote:
Victor Bazarov wrote:
>Jess wrote:
>>>
I learned that if we do "v.end()", then the returned iterator is a
temporary object and hence cannot be changed like

--v.end();

Why? It can. If an object is *temporary* it does NOT mean that you
cannot change it. The problem here is that the value is effectively
lost right after you change it, unless you store it somewhere, like

it = --v.end();

Depending on how the iterator's operator-- is written, it also might
not be legal. The subtlety here is that you can call non-const member
functions on a temporary object, but you cannot pass a temporary
object to a function through a non-const reference. The standard
doesn't say whether operator-- is a member function, just that --iter
is valid and has the appopriate effects.

struct iter1
{
iter1& operator--();
};
iter1 get1();

struct iter2
{
};
iter2& operator--(iter2&);
iter2 get2();

void f()
{
iter1 it1 = --get1(); // okay: calls iter1::operator--
iter2 it2 = --get2(); // error: can't call operator--(iter2&)
}
Right. Thanks for clarifying that. BTW, in the implementation of
the Standard library Dinkumware publishes, any of the iterators for
the standard containers have their operator--() as non-member? Just
curious.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 15 '07 #4
Victor Bazarov wrote:
>
Right. Thanks for clarifying that. BTW, in the implementation of
the Standard library Dinkumware publishes, any of the iterators for
the standard containers have their operator--() as non-member? Just
curious.
A quick grep suggests that the answer is no, but I haven't been in that
code for a year or more.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Jun 15 '07 #5
On Jun 15, 3:03 pm, Jess <w...@hotmail.comwrote:
I learned that if we do "v.end()", then the returned iterator is a
temporary object and hence cannot be changed like
--v.end();
It depends on the type of the iterator. The above will work
with most iterators (because operator--() is a member function,
and you can call member functions on a temporary), but not with
all (because an iterator can be just a pointer, and the built-in
operator -- doesn't work on temporaries).
Why is the returned iterator a temporary pointer? I think when the
result of a function is returned, then a non-temporary object is
created, with value copied from the local temporary object. If the
code above still gets us a temporary object, then I think the non-temp-
object-creation hasn't taken place yet.
I'm not sure I follow what you're trying to say. The return
value of a function is always a temporary. If you use the
function to initialize an object, the non-temporary object is
initialized by copying this temporary. (In specific cases, the
compiler is allowed to suppress the additional object, as an
optimization. Don't worry about this for now.)
Does it only happen if we do
p = v.end();
ie. assign v.end() to some variable?
Roughly speaking, named objects are not temporaries, unnamed
objects are. If you write:

iterator p = v.end() ;

p is not a temporary. The results of v.end() are, and the
non-temporary p is initialized with a copy of this temporary.
It is also said that we can't modify it because it has a built in
type. I guess "build-in" means pointer type here. This sounds to me
as if we could modify the temporary object if it is of class type.
I'm quite confused....
Understandably, in this case.

The rules for the built-in operators involve something called
lvalue-ness: the resuls of an expression are either an lvalue,
or they are not. Certain built-in operators, like -- require an
lvalue. A function call is an lvalue if and only if the return
type is a reference. (As a first approximation, temporaries are
not lvalues, everything else is. But this is very approximate;
the standard uses a different language here for a reason.)

User overridden operators are functions, and obey the rules for
function calls, not the rules for the operator they are
overriding. Thus, if operator-- is a user defined override,
then whether it can be called depends on the rules for calling
functions. If it is a member function (usually the case), then
it can be called on a temporary, even if the function is
non-const (which it definitely should be). If it is a free
function, taking a non-const reference, it can't be.

So, if the iterator returned from v.end() is a pointer, or is a
class type with a free function operator--, the expression
"--v.end()" is illegal; if the iterator is a class type with a
member operator--, it is legal.

--
James Kanze (Gabi Software) email: 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

Jun 16 '07 #6
On Jun 15, 3:49 pm, Pete Becker <p...@versatilecoding.comwrote:
Victor Bazarov wrote:
Jess wrote:
I learned that if we do "v.end()", then the returned iterator is a
temporary object and hence cannot be changed like
--v.end();
Why? It can. If an object is *temporary* it does NOT mean that you
cannot change it. The problem here is that the value is effectively
lost right after you change it, unless you store it somewhere, like
it = --v.end();
Depending on how the iterator's operator-- is written, it also might not
be legal. The subtlety here is that you can call non-const member
functions on a temporary object, but you cannot pass a temporary object
to a function through a non-const reference. The standard doesn't say
whether operator-- is a member function, just that --iter is valid and
has the appropriate effects.
Also, of course, the standard allows the use of a raw pointer as
iterator; in some implementations, vector<T>::iterator is just a
typedef for T*. In the case of a raw pointer, the rules for the
built-in operator -- apply, and not those for functions. And
the rules for the built-in operator -- require an lvalue, which
the return value of a function is not (unless the function
returns a reference).

(Just thought I'd add to the confusion.)

--
James Kanze (Gabi Software) email: 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

Jun 16 '07 #7
On Jun 15, 5:44 pm, Pete Becker <p...@versatilecoding.comwrote:
Victor Bazarov wrote:
Right. Thanks for clarifying that. BTW, in the implementation of
the Standard library Dinkumware publishes, any of the iterators for
the standard containers have their operator--() as non-member? Just
curious.
A quick grep suggests that the answer is no, but I haven't been in that
code for a year or more.
That's the current version, right? I believe earlier versions
used a typedef to a pointer for the iterator in vector---that
was certainly the most prevalent implementation five years ago.

The result is that --v.end() might fail for someone using an
older version of the compiler (VC++ 6.0, g++ 2.95.2), but work
for someone using a more recent version (I haven't tried with
VC++ 8, but it doesn't work with g++ 3.0 up.)

--
James Kanze (Gabi Software) email: 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

Jun 16 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

38
by: Grant Edwards | last post by:
In an interview at http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=273 Alan Kay said something I really liked, and I think it applies equally well to Python as well as the languages...
26
by: Michael Klatt | last post by:
I am trying to write an iterator for a std::set that allows the iterator target to be modified. Here is some relvant code: template <class Set> // Set is an instance of std::set<> class...
5
by: music4 | last post by:
Greetings, I want to STL map class. But I don't know how to use iterator. Let me state my question by following small sample: map<int, int> mymap; // insert some <key,value> in mymap ...
11
by: Mateusz Loskot | last post by:
Hi, I have a simple question about naming convention, recommeded names or so in following case. I have a class which is implemented with one of STL container (aggregated) and my aim is to...
8
by: Mateusz Åoskot | last post by:
Hi, I know iterator categories as presented by many authors: Stroustrup, Josuttis and Koenig&Moo: Input <---| |<--- Forward <--- Bidirectional <--- Random Output <---|
5
by: Mark Stijnman | last post by:
I have a question about forward iterators and what one should do or not do with them. I'm planning on writing a container that, when all boils down to it, stores a sequence of strings. I want...
3
by: wolverine | last post by:
Hi I am accessing a map from inside threads. There is a chance that an element is inserted into the map, from inside any thread. Since i don't know about thread safety of stl implementation i am...
3
by: Alex__655321 | last post by:
Hello All I hope I'm correct posting an STL question here - if not feel free to direct me to somewhere more appropriate. I'm writing some code using an std::set which I believe is the best...
16
by: Juha Nieminen | last post by:
I'm actually not sure about this one: Does the standard guarantee that if there's at least one element in the data container, then "--container.end()" will work and give an iterator to the last...
2
by: Terry Reedy | last post by:
Luis Zarrabeitia wrote: Interesting observation. Iterators are intended for 'iterate through once and discard' usages. To zip a long sequence with several short sequences, either use...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.