空大括号 作为范围的结尾

Posted

技术标签:

【中文标题】空大括号 作为范围的结尾【英文标题】:empty curly bracket as end of range空大括号 作为范围的结尾 【发布时间】:2015-05-08 12:40:10 【问题描述】:

我在 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));


以下代码来自 C++ 标准库第二版。

带有“// 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

【问题讨论】:

【参考方案1】:

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

对于stream_iterator 的情况,默认构造函数有一个特殊的含义——EOF。表示容器结束的迭代器不是默认构造的。 (在实践中,简单容器的迭代器可以只是指针)。

除了流迭代器之外的默认构造迭代器通常没有多大意义,并且在这种情况下没有您想要的语义。

(除了流迭代器之外,boost 的其他一些迭代器确实遵循与流迭代器相同的模式)。

【讨论】:

知道了。 仅表示默认构造迭代器;这是 stream_iterator 的默认构造函数的含义,使其在该上下文中变得特别。所以第二个是一个技巧,一个很好的技巧。 如今,迭代器通常不是指针,即使它们可以是指针(向量和字符串)。 @T.C.即使它们不是指针,向量和字符串迭代器通常也是指针周围的薄包装器,至少在优化构建中是这样。高效迭代器的基本假设并没有发生太大变化。例如,对于 libstdc++,这个瘦包装器称为 __gnu_cxx::__normal_iterator。

以上是关于空大括号 作为范围的结尾的主要内容,如果未能解决你的问题,请参考以下文章

节点模块 raml2html 返回空大括号

带有空大括号的 C++ 新初始化触发 cppcheck uninitvar 错误

Java中大括号的作用是啥?

将大括号用于变量范围的目的是错误的吗?

在大括号扩展范围中使用变量馈送到 for 循环

基于范围的大括号初始化器而不是非常量值?