Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ch09/ex9_32.cpp #125

Closed
dom68 opened this issue Jan 11, 2015 · 2 comments
Closed

ch09/ex9_32.cpp #125

dom68 opened this issue Jan 11, 2015 · 2 comments

Comments

@dom68
Copy link

dom68 commented Jan 11, 2015

ch09/ex9_32.cpp

FYI, I believe in Update ex9_32.cpp
iter = vi.insert(iter, *iter++); statement
will insert *iter into the container after incrementing the pointer, not before the pre-incremented iter pointer.
tested it with the statement iter = vi.insert(iter, - *iter++); so I could discriminate. The corrected statement should be instead iter = vi.insert(iter, *iter); ++iter;
this statement may also refers to the section of the book 4.1.3 Order of Evaluation, Precedence, and Associativity where incrementing the second argiment will affect the first argument in the insert function

thanks,
dom68

@Mooophy
Copy link
Owner

Mooophy commented Jan 11, 2015

Hi~ @dom68
Thx for issue reporting.
The current answer in this repo indeed has problem. But it isn't like what you said. First of all, the following statement is illegal :

iter = vi.insert(iter, *iter++); 

Because as said in Standard [5.2.2]

The order of evaluation of arguments is unspecified.

Check this post on StackOverflow for more discussion.
As a result, after entering function insert, iter could be its original value or original value + 1 or even anything else, depending on how compiler implemented.

As for your version :

iter = vi.insert(iter, *iter); 
++iter;

I tested it using the code from CP5, as this:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
    auto iter = vi.begin();
    while (iter != vi.end())
    {
        if (*iter % 2)
        {
            iter = vi.insert(iter, *iter);
            ++iter;
        }
        else
        {
            iter = vi.erase(iter);
        }
    }
    for(auto i : vi)
        cout << i << " ";
    return 0;
}

I believe it's legal, but it led to an infinite loop. Please try it.

Mooophy added a commit that referenced this issue Jan 11, 2015
pezy referenced this issue in pezy/CppPrimer Jan 11, 2015
@dom68
Copy link
Author

dom68 commented Jan 13, 2015

MooophyCpp-Primer
Thanks for you input.
dom68

Date: Sat, 10 Jan 2015 19:25:29 -0800
From: [email protected]
To: [email protected]
CC: [email protected]
Subject: Re: [Cpp-Primer] ch09/ex9_32.cpp (#125)

Hi~ @dom68

Thx for issue reporting.

The current answer in this repo indeed has problem. But it isn't like what you said. First of all, the following statement is illegal :

iter = vi.insert(iter, *iter++);

Because as said in Standard [5.2.2]

The order of evaluation of arguments is unspecified.

Check this post for more discussion.

As a result, after entering function insert, iter could be its original value or original value + 1 or even anything else, depending on how compiler has been implemented.

As for your version :

iter = vi.insert(iter, *iter);
++iter;

I tested it using the code from CP5, as this:

#include
#include
using namespace std;
int main()
{
vector vi = {0,1,2,3,4,5,6,7,8,9};
auto iter = vi.begin();
while (iter != vi.end())
{
if (*iter % 2)
{
iter = vi.insert(iter, *iter);
++iter;
}
else
{
iter = vi.erase(iter);
}
}
for(auto i : vi)
cout << i << " ";
return 0;
}

I believe it's legal, but it led to a infinite loop. Please run it.


Reply to this email directly or view it on GitHub.

                  =

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants