输入迭代器的值初始化

Value-initialization of an input iterator

本文关键字:初始化 迭代器 输入      更新时间:2023-10-16

我正在阅读《加速C++》一书的第8章。第8.3节是关于输入和输出迭代器的:

vector<int> v; // read ints from the standard input and append them to v
copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v));

[…]

要复制的第二个参数创建默认值(空)istream_iterator,它未绑定到任何文件。这个istream_iterator类型具有默认值istream_iterator已到达文件末尾或处于错误状态将显示为等于默认值。因此,我们可以使用默认值,用于指示复制

这就是我所理解的:istream_iterator是一个模板类,istream_iterator<int>是模板的一个实例。正在写入istream_iterator<int>()触发istream_iterator<int>对象,这意味着零初始化+对隐式默认构造函数的调用(http://en.cppreference.com/w/cpp/language/value_initialization)。我认为istream_iterator<int>对象也可以工作(触发器调用默认构造函数),所以我尝试了这个:

vector<int> v; // read ints from the standard input and append them to v
copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(v));

但这并不能编译:

错误:在","标记之前需要主表达式

我不明白发生了什么。欢迎任何解释。

没有办法默认初始化,而不是值初始化,一个临时的。虽然表达式type()创建了一个临时初始化的值,但单独的类型名称不是有效的表达式。

然而,对于任何声明默认构造函数的类型(如本类型),默认初始化和值初始化是等效的;在调用非隐式构造函数之前没有零初始化。

在此上下文中:

copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(v));
//                               ^^^^^^^^^^^^^^^^^^^^^

第二个参数istream_iterator<int>被解析为一个类型。您需要一个实例,因此需要(),无论是否带有参数。出于同样的原因,以下方法不起作用:

void foo(int); // function declaration
int main()
{
  foo(int);
}

不要被模板分散注意力。任何类型名称都会出现相同的问题:

struct S {};
void f(int, S);
f(1, S);   // error: S is not an object
f(1, S()); // okay: S() constructs an object

istream_iterator是一个"模板化"类提供两个构造函数:

  basic_istream<charT,traits>* in_stream;
  istream_iterator() : in_stream(0) {}
  istream_iterator(istream_type& s) : in_stream(&s) { ++*this; }

默认构造函数将in_stream初始化为用于流结束的0

所以,

istream_iterator<int>需要()进行EOF

修复:-copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v));