Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

empty curly bracket {} as end of range

I'm running on XCode, Yosemite.

Following code compiled but crashes at run time, why?

I intentionally used "{}" in the second std::copy as the "end of range".

I experimented this code because of a working example that used "{}" as "default constructed stream iterator as end of the range".

So why that(see 2nd code) one is working but this(1st code) one failed?

#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<int> coll1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    // copy the elements of coll1 into coll2 by appending them
    vector<int> coll2;
    copy (coll1.cbegin(), coll1.cend(),    // source
          back_inserter(coll2));           // destination

    vector<int> coll3;
    copy (coll1.begin(), {},
          back_inserter(coll3));

}

Following code is from The C++ Standard Library second edition.

The line with "// end of source" could be either "istream_iterator()," or simply "{},"

both works because: quoted from the book

"Note that since C++11, you can pass empty curly braces instead of a default constructed stream iterator as end of the range. This works because the type of the argument that defines the end of the source range is deduced from the previous argument that defines the begin of the source range."

/* The following code example is taken from the book
 * "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
 * by Nicolai M. Josuttis, Addison-Wesley, 2012
 *
 * (C) Copyright Nicolai M. Josuttis 2012.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 */
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;

int main()
{
    vector<string> coll;

    // read all words from the standard input
    // - source: all strings until end-of-file (or error)
    // - destination: coll (inserting)
    copy (istream_iterator<string>(cin),    // start of source
          {},       // end of source
          back_inserter(coll));             // destination

    // sort elements
    sort (coll.begin(), coll.end());

    // print all elements without duplicates
    // - source: coll
    // - destination: standard output (with newline between elements)
    unique_copy (coll.cbegin(), coll.cend(),           // source
                 ostream_iterator<string>(cout,"\n")); // destination
}
like image 960
milesma Avatar asked May 08 '15 12:05

milesma


1 Answers

The first one failed because the type of your iterator is not a stream_iterator.

For the stream_iterator case the default constructor has a special meaning - EOF. The iterator representing the end of a container is not default constructed. (In practice for simple containers iterators can be just pointers).

Default constructing iterators other than stream iterators don't make much sense usually and doesn't have the semantics you'd want in this instance.

(Some other iterators from boost besides stream iterators do follow the same pattern as stream iterators do).

like image 78
Flexo Avatar answered Sep 24 '22 15:09

Flexo