【问题标题】:Value-initialization of an input iterator输入迭代器的值初始化
【发布时间】:2013-08-02 14:30:40
【问题描述】:
我正在阅读“Accelerated 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 类型有一个默认值,其属性为 any
istream_iterator 已到达文件结尾或处于错误状态
似乎等于默认值。因此,我们可以使用
表示“one-past-the-end”约定的默认值
复制。
这是我的理解:istream_iterator是一个模板类,而istream_iterator是模板的一个实例。编写 istream_iterator() 会触发 istream_iterator 对象的值初始化,这意味着零初始化 + 调用隐式默认构造函数 (http://en.cppreference.com/w/cpp/language/value_initialization)。我认为 istream_iterator 对象的默认初始化也可以正常工作(触发对默认构造函数的调用),所以我尝试了这个:
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));
但这不能编译:
错误:“,”标记之前的预期主表达式
我不明白发生了什么。欢迎任何解释。
【问题讨论】:
标签:
c++
istream-iterator
value-initialization
【解决方案1】:
没有办法默认初始化,而不是值初始化,一个临时的。虽然表达式 type() 创建了一个值初始化的临时值,但单独的类型名称不是有效的表达式。
然而,对于任何声明了默认构造函数的类型(比如这个),默认初始化和值初始化是等价的;在调用非隐式构造函数之前没有零初始化。
【解决方案2】:
在这种情况下:
copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(v));
// ^^^^^^^^^^^^^^^^^^^^^
第二个参数istream_iterator<int> 被解析为一个类型。你需要一个实例,所以你需要(),带或不带参数。出于同样的原因,以下内容也行不通:
void foo(int); // function declaration
int main()
{
foo(int);
}
【解决方案3】:
不要被模板分心。任何类型名称都会出现同样的问题:
struct S {};
void f(int, S);
f(1, S); // error: S is not an object
f(1, S()); // okay: S() constructs an object
【解决方案4】:
istream_iterator 是一个“模板化”类
Provides two constructor :
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));