3

I am trying to learn dynamic programming by solving some questions online. One question that i came across requires the to process the following input

4 10 3 4 4 5 6 7 5 7

The first points at number of items, second the total capacity and the rest of the four (in a pair) should now point at the value and capacity.

The problem i have is with the code which parses it.

#include<iostream>
#include<map>
#include<iterator>
using namespace std;

template<typename T>
void print(typename T::const_iterator start,
           typename T::const_iterator end)
{
    typename T::const_iterator itr=start;
    while(itr!=end)
    {
        std::cout << itr->first << " " << itr->second << std::endl;
        itr++;
    }
}

int main()
{
    int _M_N; // total numbers
    int _M_V; // total values
    std::map<int,int> _M_Values; 

    istream_iterator<int> isi(cin); 
    _M_N = *isi;
    _M_V = *++isi;

    for(int i=0;i<_M_N;i++)
    {
        //int m=*++isi,n=*++isi;
        //_M_Values.insert(make_pair(m,n));
        _M_Values.insert(make_pair(*++isi,*++isi)); 
    }
    print<std::map<int,int> >(_M_Values.begin(),_M_Values.end()); 
}

when i run this program i get the wrong output for this input

   akhetarp@desktop> knapsack < test
   4 3 
   5 4 
   7 6

if i however uncomment the line and comment the earlier line for insertion, i get the expected

   int m=*++isi,n=*++isi;
   _M_Values.insert(make_pair(m,n));
   // _M_Values.insert(make_pair(*++isi,*++isi));

   3 4
   4 5 
   6 7 
   5 7 

I know it has to be some basic error. Thanks in advance,

Arun Khetarpal
  • 197
  • 1
  • 3
  • 10
  • 3
    There is no guarantee of eval-order of function parameters, so you cannot "know" that `*++isi, *++isi` will eval the first, or the second, pre increment before the other. See [this article](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) for more info. – WhozCraig Aug 25 '13 at 06:56
  • 1
    Besides the undefined behavior of `make_pair(*++isi,*++isi)`, you should never define names like `_M_N` or `_M_Values`; you are probably mimicking some STL code that you have seen, but identifiers that begin with and underscore followed by a capital letter are precisely _reserved for the implementation_ (see http://stackoverflow.com/q/228783/688659 for other reserved kinds) (by the way, STL implementations usually use `_M_xxx` for class _member_ variables, not local variables). – gx_ Aug 25 '13 at 09:29

1 Answers1

8

You are missing a sequence point here:

 _M_Values.insert(make_pair(*++isi,*++isi)); 

The comma in a declaration is one, the comma in a function not:

int m=*++isi,n=*++isi;

Please, have a look at: http://en.wikipedia.org/wiki/Sequence_point

  • 1
    +1 Or [this article](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) on this site. – WhozCraig Aug 25 '13 at 07:01