使用std :: copy时istream_iterator无效

时间:2016-03-21 14:59:26

标签: c++ iterator copy stdin

我正在尝试将ints中的一些stdin复制到vector。我有代码工作,但我不确定为什么在()的第二个参数之后我需要copy。我的意思是istream_iterator<int>()调用中的copy参数。

这里的代码......

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

using std::vector;
using std::copy;
using std::cin;
using std::istream_iterator;

int main()
{   
     vector<int> nums;
     copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(nums)); // why do I need the empty brackets after the 2nd argument?

     return 0;
}   

如果删除括号,我会从编译器中收到错误,但是如果我稍微修改代码到下面的代码,我的程序就可以了。

int main()
{   
     vector<int> nums;
     istream_iterator<int> end; // no brackets used here
     copy(istream_iterator<int>(cin), end, back_inserter(nums)); 

     return 0;
}  

我来自Java背景,因此空括号只表示您使用了空构造函数。第一个代码片段与我认为的理解相反,根据我对C ++的理解,如果你想使用一个空的构造函数,你只是错过了(),但这不是这里的情况

帮助!

3 个答案:

答案 0 :(得分:3)

该行

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

毫无意义。 istream_iterator<int>是一种不是对象的类型。您需要使用()来创建istream_iterator<int>类型的未命名的,临时的,默认构造的对象。

使用

istream_iterator<int> end;

您声明了istream_iterator<int>类型的对象,并且您不需要括号,因为它是默认构造的,没有它们。事实上,如果您使用过括号,例如:

istream_iterator<int> end();

然后你会遇到most vexing parse问题而end现在只是一个不带任何东西并返回istream_iterator<int>的函数。

答案 1 :(得分:1)

  

我的代码有效,但我不确定为什么在复制的第二个参数之后我需要()

您需要它们来构造一个迭代器,而不是声明一个表示输入流的一个接一个结尾的单独变量。如果你写

istream_iterator<int>

没有括号,这将是一个类型名称。括号是一个默认构造函数的调用:

istream_iterator<int>()

构造istream_iterator<int>对象,并作为其第二个参数传递给std::copy。按照惯例,istream_iterator<T>的默认构造函数为您提供了一个迭代器的实例,它表示流的一个接一个结束。

答案 2 :(得分:1)

它可能令人困惑,但两种情况都是默认构造函数创建对象。对于第一种情况,您必须使用(),对于第二种情况,您不得使用()

istream_iterator<int>()默认构造函数创建一个临时对象。如果没有()istream_iterator<int>只是一个类型名称,因为预期类型的​​实例没有意义。

istream_iterator<int> end;也是默认构造函数创建一个命名对象。你不能在这里使用(),否则它将成为一个函数声明,它不带参数并返回istream_iterator<int>。请参阅Most vexing parse