为什么我不能通过传递临时输入迭代器来构造一个向量?

时间:2015-06-24 02:48:39

标签: c++ vector istream-iterator

我经常使用istream_iterator将标准输入复制到这样的矢量:

copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(vec));

它有效。

今天,当我构建一个矢量时:

vector<int> vec(istream_iterator<int>(cin), istream_iterator<int>());
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));

它只是无法编译!

但如果我像这样构建它:

istream_iterator<int> beg(cin), end;
vector<int> vec(beg, end); 
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));

它有效。

为什么呢?我不能使用临时变量来构造向量吗?如果是的话,但为什么我在使用std :: copy时可以这样做?

ps:我在vs2005下编译了它,我使用了以下头文件:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

1 个答案:

答案 0 :(得分:2)

不幸的是,这是一个函数声明:

vector<int> vec(istream_iterator<int>(cin), istream_iterator<int>());

它是一个名为vec的函数,它按值返回vector<int>并采用两个参数:istream_iterator<int>,其形式参数名称为cin,并且没有正式参数名称的函数返回istream_iterator<int>,并且不带参数。

为什么?

基本上,在C ++(和C)中,如果一段代码可以解释为声明,那么它就是。

根据N3936 :: 6.8.1 [stmt.ambig]:

  

涉及表达式语句的语法含糊不清   和声明:具有函数样式的表达式语句   显式类型转换(5.2.3),因为它最左边的子表达式可以   与第一个声明者开始的声明无法区分   (a。在这些情况下,声明是声明。[注意:To   消除歧义,整个声明可能需要进行审查   确定它是表达式语句还是声明。这个   消除许多例子的歧义。 [例子:假设T是a   simple-type-specifier(7.1.6),

     

T(a) - > m = 7; //表达式语句
  T(一)++; //表达式语句
  T(a,5)&lt;&lt; C; //表达式语句

     

T(* d)(INT); //声明
  T(E)[5]; //声明
  T(f)= {1,2}; //声明
  T(* G)(双(3)); //声明

     

在最后一个例子中   在上面,g,它是指向T的指针,被初始化为double(3)。这个   由于语义原因,当然是不正确的,但这并不影响   句法分析。 - 例子]

如何修复

我们所需要的是使编译器无法将代码视为函数声明的东西。

  1. 在参数周围添加额外的括号使得它清楚 我们打算成为构造函数参数名称的编译器不能作为参数声明。

    vector<int> vec((istream_iterator<int>(cin)), istream_iterator<int>());

  2. 正如您的解决方案所示,使用命名变量作为构造函数参数。