I am curious why the following code compiles if a list iterator is
forward only and I am doing a -- on it. It doesn't seem to work though,
because my string ended with a comma on it when I expected it not to end
with a comma.
---------------
int main()
{
std::list orderIDs;
// SNIP fill it
std::string orderIDsAsString; // String of order IDs seperated by
commas
for(std::list::iterator itOrderID = orderIDs.begin();
itOrderID != orderIDs.end(); ++itOrderID)
{
orderIDsAsString += *itOrderID;
if(itOrderID != --orderIDs.end())
{
orderIDsAsString += ",";
}
}
return 0;
}
----------
So, I changed the code to this
----------
int main()
{
std::list orderIDs;
// SNIP fill it
std::string orderIDsAsString; // String of order IDs seperated by
commas
std::string orderIDsAsString;
for(std::list::iterator itOrderID = orderIDs.begin();
itOrderID != orderIDs.end(); ++itOrderID)
{
orderIDsAsString += *itOrderID;
orderIDsAsString += ",";
}
orderIDsAsString.erase(orderIDsAsString.end() - 1); // Get rid of
last comma
return 0;
}
--------
On Mon, 25 Aug 2014 13:54:10 -0500 in comp.lang.c++, Christopher Pisz
wrote,
> if(itOrderID != --orderIDs.end())
I consider that as wrong anyway; you should not attempt to modify the
value returned by .end()
On Monday, 25 August 2014 21:54:10 UTC+3, Christopher Pisz wrote:
> I am curious why the following code compiles if a list iterator is
> forward only and I am doing a -- on it.
It compiles because your knowledge is not accurate, 'std::list' is
defined to be bidirectionally linked list. It is 'std::forward_list'
that is single-linked list.
On 8/25/2014 2:54 PM, Christopher Pisz wrote:
> I am curious why the following code compiles if a list iterator is
> forward only
Isn't it bidirectional? I mean, if this compiles, it must be, no?
> and I am doing a -- on it. It doesn't seem to work though,
> because my string ended with a comma on it when I expected it not to end
> with a comma.
>
> ---------------
>
> int main()
> {
> std::list orderIDs;
>
> // SNIP fill it
>
> std::string orderIDsAsString; // String of order IDs seperated by
> commas
>
> for(std::list::iterator itOrderID = orderIDs.begin();
> itOrderID != orderIDs.end(); ++itOrderID)
> {
> orderIDsAsString += *itOrderID;
>
> if(itOrderID != --orderIDs.end())
> {
> orderIDsAsString += ",";
> }
> }
> return 0;
> }
>
> ----------
> So, I changed the code to this
>
> ----------
> int main()
> {
> std::list orderIDs;
>
> // SNIP fill it
>
> std::string orderIDsAsString; // String of order IDs seperated by
> commas
>
> std::string orderIDsAsString;
> for(std::list::iterator itOrderID = orderIDs.begin();
> itOrderID != orderIDs.end(); ++itOrderID)
> {
> orderIDsAsString += *itOrderID;
> orderIDsAsString += ",";
> }
>
> orderIDsAsString.erase(orderIDsAsString.end() - 1); // Get rid of
> last comma
>
> return 0;
> }
>
> --------
Following Jorgen's advice, change your code to
for (std::list::iterator ... ) // like yours
{
if (itOrderID != orderIDs.begin())
orderIDsAsString += ",";
orderIDsAsString += *itOrderID;
}
and your problem shall be solved, no need to erase, no doubt about the
operator--.
V
--
I do not respond to top-posted replies, please don't ask
On Mon, 2014-08-25, Christopher Pisz wrote:
> I am curious why the following code compiles if a list iterator is
> forward only and I am doing a -- on it. It doesn't seem to work though,
> because my string ended with a comma on it when I expected it not to end
> with a comma.
>
....
> So, I changed the code to this
....
I'm to lazy/tired to understand your code ... but when I want
separators between things, I always use the idiom
if this is not the first thing {
print sepparator
}
print thing
I.e. I see the separator as something which comes before all elements,
except the first one.
/Jorgen
--
// Jorgen Grahn O o .
On Thu, 28 Aug 2014 23:26:38 -0700 (PDT)
Öö Tiib wrote:
> On Wednesday, 27 August 2014 05:57:14 UTC+3, David Harmon wrote:
> > On Mon, 25 Aug 2014 13:54:10 -0500 in comp.lang.c++, Christopher
> > Pisz wrote,
> > > if(itOrderID != --orderIDs.end())
> >
> > I consider that as wrong anyway; you should not attempt to modify
> > the value returned by .end()
>
> Can you elaborate, why one should not attempt to modify it?
It will work with a list iterator (as here) because list iterators can
never in practice be raw pointers, but it would not work with many
std::vector implementations because you cannot modify an rvalue return
value which is a built-in type. It is best not to get into bad habits,
otherwise code which happens to be conforming in one implementation may
not be conforming in another.
Chris
On Wednesday, 27 August 2014 05:57:14 UTC+3, David Harmon wrote:
> On Mon, 25 Aug 2014 13:54:10 -0500 in comp.lang.c++, Christopher Pisz
> wrote,
> > if(itOrderID != --orderIDs.end())
>
> I consider that as wrong anyway; you should not attempt to modify the
> value returned by .end()
Can you elaborate, why one should not attempt to modify it?
By the logic of OP code that decrement only happens when
dereferenceable iterator value precedes one returned by that
'.begin()'. Bidirectional iterators (even the not dereferencable
one-past-end iterators) can be decremented under such condition
AFAIK.