我经常使用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>
答案 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)。这个 由于语义原因,当然是不正确的,但这并不影响 句法分析。 - 例子]
如何修复
我们所需要的是使编译器无法将代码视为函数声明的东西。
在参数周围添加额外的括号使得它清楚 我们打算成为构造函数参数名称的编译器不能作为参数声明。
vector<int> vec((istream_iterator<int>(cin)), istream_iterator<int>());
正如您的解决方案所示,使用命名变量作为构造函数参数。