Mooophy / Cpp-Primer

C++ Primer 5 answers
Creative Commons Zero v1.0 Universal
8.12k stars 3k forks source link

ch09/ex9_32.cpp #125

Closed dom68 closed 9 years ago

dom68 commented 9 years ago

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 commented 9 years ago

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.

dom68 commented 9 years ago

MooophyCpp-Primer Thanks for you input. dom68

Date: Sat, 10 Jan 2015 19:25:29 -0800 From: notifications@github.com To: Cpp-Primer@noreply.github.com CC: d_jon@hotmail.com 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.

                  =