我正在尝试将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 ++的理解,如果你想使用一个空的构造函数,你只是错过了()
,但这不是这里的情况
帮助!
答案 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。