c++ - 为什么我不能通过传递临时输入迭代器来构造 vector ?

标签 c++ vector istream-iterator

<分区>

我经常使用 istream_iterator 将标准输入复制到这样的 vector 中:

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

有效。

今天当我用这个构造一个 vector 时:

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, " "));

有效。

为什么?我不能使用临时变量来构造 vector 吗?如果可以,但为什么我在使用 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>按值并采用两个参数:istream_iterator<int>形式参数名称为 cin , 和一个没有形式参数名称的函数返回 istream_iterator<int> , 并且不带任何参数。

为什么?

基本上,在 C++(和 C)中,如果一段代码可以解释为声明,那么它就是。

根据 N3936::6.8.1 [stmt.ambig]:

There is an ambiguity in the grammar involving expression-statements and declarations: An expressionstatement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates many examples. [ Example: assuming T is a simple-type-specifier (7.1.6),

T(a)->m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5) << c; // expression-statement

T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; //declaration
T(*g)(double(3)); // declaration

In the last example above, g, which is a pointer to T, is initialized to double(3). This is of course ill-formed for semantic reasons, but that does not affect the syntactic analysis. —end example ]

如何修复

我们所需要的只是使编译器无法将代码视为函数声明的东西。

  1. 在参数周围添加额外的括号可以清楚地表明 编译器认为我们打算成为构造函数参数名称的内容不能是参数声明。

    vector<int> vec((istream_iterator<int>(cin)), istream_iterator<int>());

  2. 如您的解决方案所示,使用命名变量作为构造函数参数。

关于c++ - 为什么我不能通过传递临时输入迭代器来构造 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31016784/

相关文章:

java - 在 java 中扩展 Vector<Object> 意味着什么?

C++ 在类构造函数中填充 vector

c++ - 用 std::istream_iterator 限制 std::copy 的范围

c++ - 这个迭代器声明有什么问题

c++ - 如何为临时文件创建 std::ofstream?

c++ - C++中有 "Closing console"这样的事件吗?

c++ - 在 MSVC 的 Debug模式下分配给 std::future 时崩溃

c++ - Ubuntu 13.10 C++ OpenGL GLUT - 链接问题 - 未定义对 `glClearColor' 的引用

arrays - 循环移动向量

c++ - 使用 istream_iterator 读取字符串