我经常使用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>
不幸的是,这是一个函数声明:
vector<int> vec(istream_iterator<int>(cin), istream_iterator<int>());
这是一个名为的函数vec
,该函数返回一个vector<int>
by值并接受两个参数:istream_iterator<int>
带有正式参数名称为的cin
,和一个没有正式参数名称的函数返回istream_iterator<int>
且不带任何参数的函数。
为什么?
基本上,在C ++(和C)中,如果一段代码可以解释为声明,那么它将被解释为声明。
根据N3936 :: 6.8.1 [stmt.ambig]:
语法中涉及表达式语句和声明的模棱两可:具有函数式显式类型转换(5.2.3)作为最左边子表达式的表达式语句与第一个声明符以(。开头)的声明是无法区分的。 case语句是声明[注意:要消除歧义,可能必须检查整个语句以确定它是表达式语句还是声明。这消除了许多示例的歧义。[示例:假设T是简单类型-说明符(7.1.6),
T(a)-> m = 7; //表达式语句
T(a)++; //表达式语句
T(a,5)<< c; //表达式语句T(* d)(int); //声明
T(e)[5]; //声明
T(f)= {1,2}; //声明
T(* g)(double(3)); // 宣言在上面的最后一个示例中,g(它是指向T的指针)被初始化为double(3)。这当然是出于语义原因而形成的,但是这不会影响语法分析。—结束示例]
如何修复
我们所需要的只是使编译器无法将代码视为函数声明。
在参数周围添加额外的括号可以使编译器清楚地知道,我们打算成为构造函数的参数名称不能是参数声明。
vector<int> vec((istream_iterator<int>(cin)), istream_iterator<int>());
如您的解决方案所示,将命名变量用作构造函数参数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句