空卷括号{}作为范围的结尾

mil*_*sma 5 c++ iterator c++11

我正在Yosemite的XCode上运行.

代码编译但在运行时崩溃,为什么?

我故意在第二个std :: copy中使用"{}"作为"范围结束".

我试验了这段代码,因为一个工作示例使用"{}"作为"默认构造的流迭代器作为范围的结尾".

那么为什么(见第二个代码)一个正在工作,但这个(第一个代码)一个失败了?

#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));

}
Run Code Online (Sandbox Code Playgroud)

以下代码来自The C++ Standard Library第二版.

带有"// end of source"的行可以是"istream_iterator()",也可以是"{}",

两者都有效,因为:引用了这本书

"请注意,从C++ 11开始,您可以将空的花括号而不是默认构造的流迭代器作为范围的结尾传递.这是有效的,因为定义源范围结束的参数类型是从前一个参数推导出来的它定义了源范围的开始."

/* 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
}
Run Code Online (Sandbox Code Playgroud)

Fle*_*exo 5

第一个失败,因为迭代器的类型不是stream_iterator.

对于这种stream_iterator情况,默认构造函数具有特殊含义 - EOF.表示容器末尾的迭代器不是默认构造的.(在实践中,对于简单的容器,迭代器可以只是指针).

除了流迭代器之外的默认构造迭代器通常没有多大意义,并且在这个实例中没有你想要的语义.

(除了流迭代器之外,来自boost的其他一些迭代器也遵循与流迭代器相同的模式).

  • 得到它了.{}只是意味着默认构造迭代器; 它是stream_iterator的默认构造函数的含义,使其在该上下文中特殊.所以第二个是一个技巧,一个很好的技巧. (2认同)