std::istream_iterator<> with copy_n() and friends

前端 未结 4 1953
臣服心动
臣服心动 2020-12-05 13:59

The snippet below reads three integers from std::cin; it writes two into numbers and discards the third:

std::vector num         


        
4条回答
  •  南方客
    南方客 (楼主)
    2020-12-05 14:17

    Unfortunately the implementer of copy_n has failed to account for the read ahead in the copy loop. The Visual C++ implementation works as you expect on both stringstream and std::cin. I also checked the case from the original example where the istream_iterator is constructed in line.

    Here is the key piece of code from the STL implementation.

    template inline
        _OutIt _Copy_n(_InIt _First, _Diff _Count,
            _OutIt _Dest, input_iterator_tag)
        {   // copy [_First, _First + _Count) to [_Dest, ...), arbitrary input
        *_Dest = *_First;   // 0 < _Count has been guaranteed
        while (0 < --_Count)
            *++_Dest = *++_First;
        return (++_Dest);
        }
    

    Here is the test code

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        std::stringstream ss;
        ss << 1 << ' ' << 2 << ' ' << 3 << ' ' << 4 << std::endl;
        ss.seekg(0);
        std::vector numbers(2);
        std::istream_iterator ii(ss);
        std::cout << *ii << std::endl;  // shows that read ahead happened.
        std::copy_n(ii, 2, numbers.begin());
        int i = 0;
        ss >> i;
        std::cout << numbers[0] << ' ' << numbers[1] << ' ' << i << std::endl;
    
        std::istream_iterator ii2(std::cin);
        std::cout << *ii2 << std::endl;  // shows that read ahead happened.
        std::copy_n(ii2, 2, numbers.begin());
        std::cin >> i;
        std::cout << numbers[0] << ' ' << numbers[1] << ' ' << i << std::endl;
    
        return 0;
    }
    
    
    /* Output
    1
    1 2 3
    4 5 6
    4
    4 5 6
    */
    

提交回复
热议问题